아이폰어플개발정보2010. 6. 24. 14:21
iPhone Tutorial - 투명한 뷰 띄우기
뷰를 띄우는 쪽에서는 이런식으로. 중요부분은 백그라운드칼라를 재지정하는 것이다.
   
SeconViewController *viewctrl = [[SeconViewController alloc] initWithNibName:nil bundle:nil];
[viewctrl view].backgroundColor = [UIColor clearColor];
[self.view addSubview: viewctrl.view];

뷰를 닫는쪽은 띄워진 뷰다.
[[self view] removeFromSuperview];

근데, 이걸 알아내는데 고생을 한 배경이
뷰를 띄울때
[self presentModalViewController:viewctrl animated:YES];
이런 식으로 띄우면 절대 통하지 않는다는거다.



출처 : http://blog.naver.com/PostView.nhn?blogId=suny4rang&logNo=50084528217
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 24. 14:21
iPhone Tutorial - TouchXML 사용법
TouchXML 을 사용하기 위해서는 프로젝트에 TouchXML 라이브러리를 추가해야 한다.
방법은..
1. TouchXML 소스를 프로젝트에 추가한다. 다운로드
2. TouchXML 은 lib2 를 사용하기 때문에 이를 프로젝트 콘피그에 설정해줘야 한다.
  • Setting 항목의 Search Paths 그룹의 Header Search Paths에 /usr/include/libxml2 값 설정.
  • Setting 항목의 Linking 그룹의 Other Linker Flags에 -lxml2 값 설정


이제 코딩으로 들어가보자.
사용하기 위해 임포트 먼저 하고
#import "TouchXML.h"

그리고 XML 파일을 읽어야겠지?
- (IBAction)doTouchXML {
   
    NSBundle* bundle = [NSBundle mainBundle];
    NSString* strXMLFIlePath = [bundle pathForResource:@"book" ofType:@"xml"];
    NSData *ndXMLFromFile = [[[NSData alloc] initWithContentsOfFile:strXMLFIlePath] autorelease];
   
    CXMLDocument *xmlParser = [[[CXMLDocument alloc] initWithData:ndXMLFromFile
                                                          encoding:NSUTF8StringEncoding options:0 error:nil] autorelease];

    NSArray *arrXmlNode = [xmlParser nodesForXPath:@"//book" error:nil];
    NSLog(@"BOOK COUNT: %d", [arrXmlNode count]);

CXMLDocument 객체를 이용해서 XML 파일을 읽어들이고 있다. 그리고는
XPathQuery 를 날려서 이를 배열로 받는데 각 배열안에 들어있는 오브젝트는 CXMLElement 이라는 자료형이다.




출처 : http://blog.naver.com/PostView.nhn?blogId=suny4rang&logNo=50084951521
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플정보2010. 6. 24. 14:11
App Store 상위 100위 무료 App. 평균 광고 수익 - 매일 $400
이미 아시는 분들은 다 아시는 거겠지만, 혹시나 해서...
우연히 트위터 쫓아가다보니, http://twitter.com/iPhoneDevGuy
의 트위트 중에서 발견하게 되어 아는척 (-_-) 해 봅니다.

기존에 제가 퍼 올린글 "iPhone / iPod Touch 무료 광고어플로 먹고 살수 있을까?"
(http://cafe.naver.com/mcbugi/3654) 에서는 광고보다는 싸게라도 파는게 남는 장사라는
Pinch Media의 2009년 2월달 자료를 베껴왔었는데, 이번 5월에 adwhirl에서 발표한
자료 (http://www.scribd.com/doc/15007502/Adwhirl-iPhone-Advertising-Snapshot)
에서는 무료 어플리케이션 상위 100위권은 하루에 $400~5,000의 수익을 올린다고 합니다.

평균 CTR (Click-Through Rate): 2.6%
평균 eCPM (effective Cost-Per-thousand iMpressions): $1.90
평균 fill rate (광고 요청해서 성공적으로 광고가 단말기에 뿌려진 비율): 60%

그래서 Facebook 이나 Myspace에서 광고를 올리는 경우보다 최대 8배 가량 높다고 하네요.
그러나 두달 지나면 광고 수익이 줄어든다고 합니다.

그리고 마지막으로 자기네 서비스를 이용하면 Rollover (여러 ad network 중 가용한
서비스들을 접속하는 방식) 에 의해서 fill rate를 100%까지 올려준다는 광고... ^^;

그동안 광고에 대해서 고려하지 않았다면, 다시한번 고려해볼만 할 것 같습니다.
(http://www.adwhirl.com/)
just my $0.02


출처 : http://blog.naver.com/PostView.nhn?blogId=gonagi&logNo=150048404167
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플정보2010. 6. 24. 11:46
visor - 터미널 자주 쓰시는분들~ 편하게 쓰세요
맥에서 작업을 할때 어디서든 터미널 부르기..
쓰시는분들도 많이 계실 듯 한데요.


터미널 작업 많이 하시는분들은 쓰시면 좋을것 같네요.

일단 여기에 설치 방법이 나와있습니다.
설치법설명을 보면
1. SIMBL 설치 <-- 링크 클릭 다운로드후에 설치해주세요.
2. http://code.google.com/p/blacktree-visor/  여기 오른쪽에 다운로드 링크로  Visor를 다운로드 받구 압축을 풀면 Visor.bundle 이라는 파일이 나오는데요. 이거를 ~/Library/Application Support/SIMBL/Plugins  여기에 넣어줍니다.
3. 터미널을 (재)실행 해주시구요.

일단 여기까지하면 잘 되실겁니다. 터미널 메뉴에 Visor Preferences... 이라고 생기게 되는데요.
여기서 설정을 바꿔주실 수 있습니다.

어디에 있는 창을 많이 띠워놓았든 상관없이 단축키    "컨트롤 + f1" 누르시면 가장 상위화면으로 터미널이 뜹니닷!!

iterm을 쓰다가 이거 알게된 다음부터 기본 터미널로 계속 쓰고 있는데 편하네요.ㅋ
터미널 자주 쓰시는분들 편하게 사용하세요~
 


출처 : http://blog.naver.com/PostView.nhn?blogId=gonagi&logNo=150043117815
Posted by 오늘마감

댓글을 달아 주세요

아이폰기본사용2010. 6. 23. 21:12
'아이폰 상식' - iPhone 해킹시 자주 언급되는 용어들...

1. 펌웨어

많이들 아실겁니다...

기기를 운영할수 있게 만든 각종 OS나 설정 등을

저장한 화일입니다...기기의 오작동이나 에러를

 소프트웨어로 수정할때 펌웨어를 업그레이드해서 해결을 하죠...

아이폰의 경우 1.0.0 에서 현재 1.1.3 까지 나와있는 상태입니다...

초기 아이폰 펌웨어는 대략 90-100 메가 정도였으나

 현재는 150 메가 정도 됩니다...

2. 액티베이션

아이폰은 전화기입니다...

당연히 전원을 넣고 심카드를 넣으면 전화가 되어야 합니다...

그러나 우리의 위대한 잡스형님께서는 이익의

 극대화를 꾀하고자 미국의 AT&T와 2년간의 미국내

독점 계약을 하시게 되죠...

그래서 아이튠즈를 통한 AT&T 인증을 받은 전화기만

 제대로된 기능을 발휘하게 막아 놓으셨답니다...

이 인증 과정을 액티베이션이라고 하면 처음 인증시 15불인가

하는 수수료 까지 내야 한다는 어처구니 없는 상황입니다...

아이폰이 전화로써의 제 기능을 하기 위해

처음 통과해야 하는 과정이 액티베이션입니다...

전화기능이 없고 아무런 독점 제약이 없는 아이팟

 터치의 경우 액티베이션 과정이 당연히 없습니다...

2. 제일브레이크

다들 탈옥이라고 알고 계신 그놈입니다...

아이폰은 용량에 따라 초기 4기가에서 현재의 16 기가까지의

 저장 공간을 가집니다...

그중 약 300 메가를 시스템 파일 영역이라 하여 OS 및

어플리케이션이 설치되어 있고 

8 기가짜리라면 약 7.7 기가 정도의 저장공간이 음악과

동영상용으로 사용되어집니다...

하지만 우리의 위대한 해커님들께서 이 공간을 사사로이(?) 이용하시고자

접근이 거부된 화일 디렉토리 시스템에 접근하여

 읽기와 쓰기를 인위적으로 가능하게 만드는 작업...

이것이 바로 제일브레이크 입니다...

그러니까 접근이 거부된 아이폰 내부를 유저가 마음대로

 비공식 어플리케이션을 깔고 지우고 사용할수 있게 하는 과정을

제일브레이크라고 하는 것입니다...

이 과정을 거치지 않으면 우리는 단순히 아이튠즈를 이용해서

 음악과 동영상의 동기화 만을 해야합니다...

3. 언락

액티베이션 & 제일브레이크와 상당히 혼동하시는 개념입니다...

액티베이션과 제일브레이크 그리고 언락은 완전히 다른 말입니다...

초기 락을 푼다는 의미에서 액티베이션,

자일브레이크와 혼동해서 사용했지만

개념을 확실히 잡으셔야 합니다...

언락은 GSM 캐리어를 유저가 마음대로 사용할수 있게

 전화기의 Sim 카드 락을 푸는 것을 말합니다...

원래 AT & T 만을 사용하도록 락이 걸린 아이폰을 기타

다른 GSM 캐리어의 심카드를 인식시켜

전화로써의 기능을 수행하게 만드는 것... 바로 이 해킹

 과정이 언락입니다...언락을 하게되면 여타 전세계

 모든 나라의 GSM 망에서 사용 가능한 심카드를

 아이폰이 인식을 합니다...

이 과정을 거치지 않으면 올바르지 않는 심카드라는

오류 메세지가 뜨며 전화 기능이 활성화 되지 않습니다...

GSM 망을 사용하는 나라에서 아이폰을 전화기로

사용하기 위한 필수 과정입니다...

망할 WCDMA 국가인 한국과 일본은 전세계에서 열외입니다.

4. 부트로더

부트로더는 말 그대로 오에스를 부팅해서

기기가 작동할수 있게 만드는 영역입니다...

하지만 불행히도 애플에서 위에 언급한 언락을 막기 위해

 이 영역에 락을 걸어 버려 언락을 못하게 만들었습니다...

그것이 한때 공포의 대상이였던 부트로더 3.9 와 4.6 입니다...

현재 부트로더 3.9에 대한 소프트웨어 심언락은 완료되었고

 순수 4.6에 대한 것도 처음 아이폰을 하드웨어적으로 언락했던

어린 친구가 작업중이라고 합니다...

5. 모뎀 펌웨어

말그대로 전화기능을 사용하기 위한 전화

 모뎀의 펌웨어 버전입니다...

04.03.13G 뭐 이런 말들 많이 들어 보셨을 겁니다...

위에 언급한 언락을 위해 반드시 해킹을 해야 하는 부분입니다...

1.1.1, 1.1.2, 1.1.3 등 아이폰의 펌웨어가 올라가면

 따라서 모뎀 펌웨어도 올라갑니다...

언락을 하기 위해 1.1.3의 펌웨어에서 모뎀 펌웨어만

1.1.2 용 모뎀 펌웨어로 다운그레이드한후

언락을 진행하여 다른 통신사 심카드를 사용하는

방법등이 해커들을 통해 이루어 졌습니다...

이것을 막고자 위에 말씀드린 부트로더에 락을 건것입니다...

아무튼 언락을 하시려면 반드시 이해하고

넘어가야할것이 모뎀 펌웨어입니다...

6. 데브팀? 네이트 트루? 지브리?

해킹을 따라하다보면 많이 나오는 이름들입니다...

한마디로 각자 아이폰을 해킹했던 해커들 이거나 모임입니다...

네이트 트루는 ibricker 라는 윈도우용 액티베이션과

 언락툴을 최초로 만든 사람입니다...

펌웨어 1.1.1 이전까지는 ibricker 가 대세였습니다...

1.1.1에서 아이폰 펌웨어의 보안구멍을 이용해서

비상전화로 액티베이션과 제일브레이크하는 방법이

 나오기 전까지는 말입니다... 

이번 1.1.3 언락 과정에서 데브팀과 협력하다 의견

 충돌로 데브팀보다 먼저 1.1.3 제일브레이크를

독단적으로 공표한 인물입니다...

그 일로 데브팀에서 네이트 트루를 매장하려고 한다는

루머까지 있었습니다... 사실일지도 모릅니다 ^^*

아무튼 가장 먼저 해킹방법을 선보인 네이트 트루는

 그 일로 인스톨러에서 자신의 툴들이 삭제되는 치욕을 맛보고

데브팀에서는 이런 저런 이유로 네이트 투르는

법적 조치를 당할꺼라는 말을 공공연히 합니다...

하지만 분명히 말씀 드릴수있는것은 현재의 어떤

해킹툴보다 네이트 트루의 툴이 문제가 없었으며

권한 설정 문제나 이런 것이 전혀 없는 가장 이상적인

 방법이였다는 것입니다...

그 후 데브팀이 1.1.3-3 까지 업데이트 하며 자일브레이크에

 따른 권한 문제등을 고치려했지만 불완전하구요...

항간에는 데브팀이 애플과 모종의 결탁을 했다는 말이있습니다...

그것 때문에 네이트 트루나 지브리 같은 사람들이

다른 해커들과 함께 데브팀과 결별했다는 설도 있구요...

그리고 지브리는 마찬가지로 ziphone 이라는

혁신적인 해킹 툴을 만든 사람입니다...

기존의 해킹방법은 1.1.1 펌웨어로 돌아가서 액티베이션과

 제일브레이크를 하고 다시 1.1.2로 업데이트하고

거기서 다시 제일브레이크를 하고 그리고 최종적으로

1.1.3 으로 업데이트하는 것이였지만

지브리는 혁신적으로 순정 1.1.3 펌웨어에서 단 45초만에

 엑티베이션과 제일브레이크를 하는 툴을 공개합니다...

데브팀에 의해 그 효과가 공격 당하고 구라라는

 말까지 있었습니다...

아이폰 펌웨어 기반이라 아이폰에서의 성공률이

 상당히 높은 해킹 툴입니다...

다만 BSD 무한 루프 같은 문제로 인해 아직까지는

 배척 당하고 있습니다...

하지만 성공만 한다면 가장 쉽고 편한 해킹

 툴이라는데는 이견이 없습니다...

액티베이션과 제일브레이크 45초...

언락까지 4분 30초...

이보다 더 쉽고 편한게 있을까요?

7. 복원

펌웨어 리스토어 즉 기기를 초기 상태로 돌리는 것을 말합니다...

아이튠즈를 실행하면 아이폰을 인식하고...

인식된 장비란의 아이폰을 찍으면 첫 화면에 업데이트와

 복원 단추가 보이죠...

여기서 복원 버튼을 누르면 아이폰은 초기 상태로 돌아갑니다...

액티베이션부터 다시 해야되는 상태를 말합니다...

다만 마지막에 인스톨된 펌웨어 버전으로 복원됩니다...

산지 1년 된 초기 1.0.0 버전 아이폰이더라도 1.1.3 펌웨어로

업데이트 해서 사용하다가

복원을 누르면 1.1.3 펌웨어가 깔린 초기 상태로

 복원된다는 말입니다...그럼 최신 펌웨어로만 복원이 되느냐?

네 그렇습니다... 원래는 그런줄 알았습니다만...

우리의 똑똑한 해커님들이 방법을 찾아냈죠...

이름하여 강제 펌웨어 다운그레이드...

아이폰은 복구모드라는 것이 존재합니다...

아이튠즈에서 복원 키를 눌러서 복원하는 것은

일반적인 복구 입니다... 아래 버전으로의 펌웨어

다운로드가 이루어질수 없습니다...

그렇기 때문에 강제 펌웨어 다운로드를 위해서는 일명

 DFU 모드라는 것을 만들어 주어야 합니다...

쉽게 DFU 모드를 만들어 주는 프로그램도 있습니다...

예전부터 쓰던 수동 방법으로는 홈키와 전원키를

 계속 누르다 보면 전원이 꺼졌다가 다시 켜지며

 사과 로고가 나옵니다... 

이때 홈키는 누른채 전원 버튼에서만 손을 떼면

화면에 아무것도 나타나지 않는 검은 바탕이 되면서

아이튠즈가 복구 모드를 인식하고 팝업이 됩니다...

여기서 쉬프트 키를 누르고 복원 버튼을 눌러 다운그레이트할

펌웨어를 눌러주면

강제로 기기의 펌웨어가 지정된 하위 버전으로 복원되는 것입니다...

아이폰이 벽돌이 됐다고 걱정하시는 분들께서는 이

방법으로 복원 모드로 들어가서 복원을 하면 벽돌이 풀립니다...

몇가지 복원 방법을 알려드리면...

- 홈 + 전원키 계속 누르고 사과 마크 나올때 전원에서 손을 땐다.

- 홈 + 전원키 아이튠즈 실행될때까지 끝까지 누르기...

- 정상적으로 밀어서 전원 끄기로 전원을 끈후 케이블을

 제거하고 홈 버튼을 누른채 케이블을 연결해서

  아이튠즈가 실행되면 복원 모드로 들어가는 방법...

ziphone 2.4는 이 방법으로 복원을 한 후 제일브레이크를 하더군요... 

8. 인스톨러

제일브레이크를 실행하면 기본적으로 깔리는

 가장 기초적인 써드파티 프로그램입니다... 

인스톨러를 통해 각종 소스나 프로그램들을 무선

 인터넷으로 다운 받아 아이폰 내부에 설치하게 해주는

기초적인 프로그램입니다...

수많은 개발자들이 개발한 공짜 프로그램을 소스

 추가라는 간단한 작업을 통해

온라인으로 설치할수 있게 만드는 핵심이 바로 인스톨러입니다...

항간의 루머에는 이 인스톨러를 만든 개발팀이 애플과 계약을 맺고

향후 업데이트부터는 아이튠즈를 통해 유료로

 할꺼라는 우울한 루머가 있습니다...

제발 아니기를 빕니다...

9. 안정화

아이폰은 위에서 말씀드린대로 300 메가 정도의

시스템 영역과 나머지의 음악, 동영상 영역이 있습니다...

시스템 영역에 깔리는 운영체계와 어플들로 인해 시스템

영역의 용량은 20메가 전후밖에 남지 않습니다...

그곳에 제일브레이크를해서 프로그램을 깔면 몇개 못깔겠죠?

그래서 나온것이 안정화라고 얘기하는 것입니다...

용량을 많이 차지하는 폰트 폴더와 어플리케이션

 폴더를 다른 영역으로 옮기고

권한을 부여해 마치 옮기지 않은것 처럼 꾸미는 일...

이것이 안정화 입니다...

인스톨러에서 설치한 보스툴을 이용해서 폰트

이동과 어플리케이션 이동을 마치면

초기 20메가 남짓이던 시스템영역의 남은 용량이 약

100 메가 이상으로 늘어납니다...

그만큼 인스톨러로 깔수 있는 써드파티 어플리케이션의

 양이 늘어난다는 것이지요...

-애플 아이폰-



출처 : http://blog.naver.com/PostView.nhn?blogId=mytelelink&logNo=20102148783
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 17:54
과제B - 모델, 뷰, 컨트롤러의 생성과 연동

과제B. Hello Poly (Part I)원문: Assignment 2B - Hello Poly (Part I)

Hello Poly 과제에서는 지난 회에서 만든 PolygonShape 클래스를 이용하여
화면에 다각형을 표시하는 iPhone 어플리케이션을 만들어갈 것이다.
우선 Part I 에서는 면(numberOfSides)을 입력받는 화면을 만들것이고
다음 Part II 에서는 실제로 다각형을 그려본다.


모델, 뷰, 컨트롤러의 생성과 연동


1. HelloPoly라는 이름의 iPhone OS application의 “Window-Based Application” 을 생성한다.

2. 유저인터페이스를 배치한다.

3. 컨트롤러를 생성하고 UI element와 연동시킨다.

4. PolygonShape를 import 한후 컨트롤러와 연동시킨다.

5. 유저의 화면 조작에 의해 실행되는 action 메소드를 구현한다.

6. polygon 오브젝트를 초기화 시키는 awakeFromNib를 구현한다.

7. 화면 조작에 의한 결과를 값의 증감, 다각형의 형태에 반영시키도록 한다.
    • 증가 버튼을 누르면 그 결과에 따라 다각형이 변하도록 만든다.

8. 면(number of sides)의 값이 최소 또는 최대값에 다다르면 유저인터페이스의 요소들을 활성화 또는 비활성화 시키도록 한다.
    • 면(number of sides)의 값이 최소에 다다르면 감소 버튼을 비활성화 시킨다.
    • 면(number of sides)의 값이 최대에 다다르면 증가 버튼을 비활성화 시킨다.


<추가 Task>

• 화면에 다각형의 내각과 라디안을 표시하는 텍스트라벨을 추가한다.
• 사용할 수 있는 다각형의 최대, 최소 값 정보를 표시하는 텍스트라벨을 추가한다.
• 다각형 이름을 표시할 수 있는 텍스트라벨을 추가한다.


■ 튜토리얼 원문: HelloPoly Walkthrough

<개요>

코코아 터치 어플리케이션을 만들기 위한 스텝 바이 스텝 튜토리얼로, 과제B를 완성시키기 위한 힌트이다.

결국 만들고자 하는것이 아래 이미지와 같다는것을 염두에 두고 진행한다.
이 컨트롤러 오브젝트에 유저인터페이스 요소들과 연동되는 인스턴스 변수를 선언해야 한다.


새로운 Cocoa Touch 프로젝트를 생성한다:
1. 메뉴의 File > New Project… 를 선택.
2. iPhone OS Application을 선택한 후, Window-Based Application 템플렛을 선택한다.
3. 프로젝트 명을 ‘HelloPoly’로 지정한다.


Active SDK 설정하기

편의를 위해서 여기서는 iPhone Simulator를 사용하도록 한다.
iPhone 어플리케이션을 개발할때 개발자는 어떤 플랫폼을 대상으로 개발할 것인지 Xcode에서 설정해주어야 하는데
이 Active SDK를 변경하기 위해서는 메뉴의 Project > Set Active SDK에서 ‘Simulator - iPhone OS 2.0’를 선택한다.

이와 관련하여 편리한 ‘Overview’ 라는 툴바 팝업이 있다.
이것은 Active SDK 와 Build Configuration(주로 debug또는 release)을 동시에 설정하도록 해준다.
메뉴의 View > Customize Toolbar... 를 선택한후 툴바에 이 팝업을 추가하면
iPhone 어플리케이션을 개발하면서 SDK를 전환할때 편리하게 쓸수 있다.


중간점검: 빌드(Build) 와 테스트
이 프로젝트는 이미 Cocoa Touch application의 골격(skeleton)을 사용하여 만들어졌다.
툴바의 “Build and Go”를 눌러 어플리케이션이 시뮬레이터로 기동되는지 확인해보자.
여기서 사용하고 있는 템플렛은 가장 기본이 되는 공백뷰(empty view)만 있는 템플렛으로 나머지는 직접 추가해야 한다.
처음부터 컨트롤을 배치해주는 다른 템플렛들도 있는데 이것은 필요에 따라 다른 과제에서 사용해보도록 한다.


Interface Builder 사용하기
위에서 확인해본 공백뷰(empty view)는 MainWindow.xib 파일에 정의되어 있다.
xib(“interface file” 또는 “nib file” 이라고 불리운다) 파일은 인터페이스 빌더에서 설정/연결된 오브젝트 정보를 포함한다.
Xcode 프로젝트 템플렛은 일반적으로 실행시 “MainWindow.xib”라는 파일을 부르도록 설정되어 있으며
이 인터페이스 파일은 어플리케이션의 메인위도우나 다른 유저 인터페이스를 포함한다.
디자인 화면에서 xib 파일을 저장하면 오브젝트의 상태들이 이 파일에 저장된다.
런타임 환경에서는 xib파일이 로딩되어 저장되어 있던 오브젝트의 상태들이 다시 실제 오브젝트에 반영된다.
MainWindow.xib를 더블클릭하면 인터페이스 빌더가 기동될 것이다.
(인터페이스 빌더는 /Developer/Applications 에 있다.)


Tip: 인터페이스 빌더의 메뉴에서 (편의를 위해) 인터페이스 빌더 외의 다른 툴들은 숨기도록 설정 할수 있다.


인터페이스 빌더를 이용하여 아래 4가지 작업을 한다:

<순서>
1. 유저 인터페이스를 배치하고 설정한다.
2. 컨트롤러 클래스를 정의하고 인스턴스화 한다.
3. 유저 인터페이스와 컨트롤러를 연결한다.
4. 새로운 컨트롤러 클래스를 위해 소스 파일을 생성한다.

1. 유저 인터페이스를 배치하고 설정한다. +-----+-----+-----+-----+-----+

아래와 같은 유저 인터페이스를 만든다:


Library 윈도우는 윈도우에 드래그하여 배치할 수 있는 많은 오브젝트를 제공한다.
여기에는 미디어 리소스(이미지, 사운드등)에 억세스할수 있는 오브젝트도 있다.


1. Cocoa Touch Plugin아래 있는 오브젝트를 선택한다.
2. 두개의 push 버튼을 윈도우에 추가한다.
3. 두개의 텍스트 라벨을 윈도우에 추가한다.
하나는 왼쪽에 배치하여 “Number of sides”라고 표시하고 나머지 하나는 오른쪽에 배치하여 값을 표시한다.


Attributes Inspector:

메뉴의 Tools > Attributes Inspector 를 선택하면 석택한 아이템의 속성값을 표시할 수 있다.


라벨의 타이틀을 편집하려면 Attributes Inspector에서 Text값을 편집하던가 라벨을 더블클릭하여 직접 바꿀수 있다.

1. Attributes Inspector가 화면에 없다면 Tools > Attributes Inspector 을 선택하여 표시하도록 한다.
2. 화면에 배치한 텍스트 라벨을 선택한다.
3. 왼쪽 라벨에 “Number of sides:” 라고 표시한다.
4. 오른쪽 라벨은 “5”라고 표시한다 (여기서 사용할 디폴트 값)
5. 버튼의 표시 텍스트(title)를 바꾸기 위해 버튼을 더블클릭한다.
6. 왼쪽 버튼은 “Decrease”로 표시한다.
7. 오른쪽 버튼은 “Increase”로 표시한다.

2. 컨트롤러 클래스를 정의하고 인스턴스화 한다. +-----+-----+-----+-----+-----+

■ 컨트롤러 클래스를 정의해보자

컨트롤러 클래스는 화면의 두 버튼과 값을 표시할 텍스트 라벨의 참조를 위한 인스턴스 변수를 가진다.
이 참조는 outlet(콘센트) 이라고도 한다. 또한 버튼에 대한 액션 메소드도 만들어야 한다.


1. 라이브러리의 Cocoa Touch Plugin 아래에 있는 Controllers 그룹을 선택한다.
2. Object 아이템을 선택한다. 이 아이콘은 유저가 정의한 유저정의 오브젝트를 의미한다.


3. 오브젝트 아이콘을 인터페이스 도큐먼트 윈도우로 드래그한다.
4. 도큐먼트 윈도우의 Object 아이템을 선택한다.
5. 메뉴의 Tools > Identity Inspector 를 이용하여 인스펙터 윈도우를 표시한다.
6. Class 필드에 Controller 라고 입력한다. 도큐먼트 윈도우의 이름이 업데이트 된것을 확인한다.


또한 클래스에 outlet(콘센트)이나 액션을 추가하기 위해서는 Identity Inspector 를 이용한다.

outlet(콘센트)을 유저정의 클래스에 추가하는 방법은:
1. 컨트롤러 오브젝트를 선택한 상태로
2. Class Outlets 섹션에 아래와 같은 outlet과 type을 정의한다.

Outlet Type
numberOfSidesLabel UILabel
decreaseButton UIButton
increaseButton UIButton

3. Class Actions 섹션에는 두가지 액션을 추가한다. 처음 액션을 ‘increase’ 로 세팅하고 두번째를 ‘decrease‘로 세팅한다.


인스펙터는 다음과 같아질 것이다:

3. 유저 인터페이스와 컨트롤러를 연결한다. +-----+-----+-----+-----+-----+

컨트롤러 클래스의 정의가 끝났음으로 인터페이스 파일내에 인스턴스가 존재한다.
이제 유저 인터페이스와 컨트롤러의 연결을 설정해보자.


Outlet(콘센트)과 연결하기


우선 outlet과 연결해보자. outlet 은 오브젝트간의 참조라고 할수 있다.


컨트롤러에서 텍스트 라벨로의 연결을 설정하기 위해서는:
1. 도큐먼트 윈도우 안의 컨트롤러를 선택한다.
2. 메뉴의 Tools > Connections Inspector 을 이용하여 적절한 인스펙터를 표시한다.
Connections Inspector(연결 인스펙터)에는 모든 사용가능한 outlet과 액션이 선택되어져 있을 것이다.

3. outlet과 action들 옆에는 동그란 모양의 “connection circle” 이 있는데 이것을 ‘numberOfSidesLabel’ outlet 옆의
텍스트 라벨에 끌어온다. 여기서는 타입이 맞는 outlet과 object만 연결가능하다.(여기서는 UILabel)

4. 연결하고자 하는 곳의 끌어왔을때 선택가능한 부분이 반전될것인데 그때 마우스 버튼을 놓으면 된다.

5. 인스펙터는 연결이 확립되었을때 아래와같이 표현된다. 나머지 outlet에 대해서도 같은 작업을 반복한다.


런타임 환경에서 컨트롤러 오브젝트는 이 컨트롤에 대한 참조를 가지게 될 것이며 메세지를 전달(호출/실행)할수 있게 된다.


변경을 저장한다.


■ 버튼의 타켓과 액션을 설정한다


모든 컨트롤은 오브젝트에 대한 참조를 가질수 있는데 이것을 타켓이라고 부른다.
그리고 타켓에서 불리는 메소드를 액션이라고 부른다.
어플리케이션이 실행되면서 특정 이벤트가 발생할때 컨트롤은 타켓의 액션을 실행한다.
이 어플리케이션에서는 버튼을 컨트롤러에 연결시키고 버튼이 클릭되었을때 증가/감소 메소드가 실행되도록 해보자.


컨트롤의 연결을 확립시키는 방법은 바로 위에서 outlet을 설정한 방법과 매우 비슷하다.


1. Increase 버튼을 선택한다.
2. Connections Inspector 가 없다면 메뉴의 Tools > Connections Inspector 를 실행시켜 보이게 한다.
3. 인스펙터에는 컨트롤을 지원하는 이벤트 리스트가 보이는데 해당 동그라미를 클릭하여 드래그 할 수 있다.
여기서는 “Touch Up Inside”(컨트롤의 안쪽을 터치했다 떼었을때) 이벤트를 사용한다.
Touch Up Inside이벤트 오른쪽의 동그라미를 끌어다가 컨트롤 오브젝트에 연결한다. 여기까지가 타켓을 설정하는 방법이다.


4. 위에서 끌어다가 오브젝트에 연결시키기 위해 마우스 버튼에서 손을 떼면(release) 타겟에서 실행할 수 있는
액션 메소드가 팝업으로 표시된다. 여기서는 두가지 액션 메소드가 보일 것이다. increase 메소드를 선택한다.


이 부분이 액션을 설정하는 부분이다.
5. Decrease 버튼에 대한 타켓과 액션도 같은 방법으로 설정한다.


변경을 저장한다.


4. 새로운 컨트롤러 클래스를 위해 소스 파일을 생성한다. +-----+-----+-----+-----+-----+

Interface Builder안에 컨트롤러 클래스를 정의했지만 실제로 생성하는 Objective-c소스 코드를 적지 않았기때문에
이 단계에서 컴파일&실행을 하려고 하면 에러가 날 것이다.
왜냐하면 nib파일이 로딩 되었을때 컨트롤러 오브젝트가 생성 되어야 하는데 코드가 존재 하지 않기 때문이다.
시험삼아 실행해 보면 아래와 같은 에러를 볼 수 있을 것이다.
“Unknown class Controller in Interface Builder file.“


컨트롤러 클래스를 위한 소스를 적어주기 위해서는:
1. document window에서 Controller 오브젝트를 선택한다.
2. 메뉴의 File > Write Class Files... 를 선택한다.
3. Save 파넬이 나타날 것이다. 여기서 헤어파일도 같이 생성된다. 디폴트 세팅으로 저장한다.
4. 새로 만들 파일을 프로젝트에 추가할 것인지 묻는 다이얼로그가 나온다.
다이어로그에는 프로젝트에 정의된 모든 타겟이 나오는데 여기서는 HelloPoly밖에 존재 하지 않음으로 하나만 나온다.
HelloPoly를 선택하고 Add 버튼을 누른다.

Xcode로 전환되며 새로 만들어진 파일을 편집할 수 있게 된다.

nib파일의 모든 변경을 저장한다.

여기까지가 인터페이스 정의이다.

컨트롤러 클래스 살펴보기

Xcode로 돌아간다.
Controller.h 와 Controller.m가 프로젝트에 추가된 것을 확인 할 수 있다.

헤더 파일을 더블클릭하여 살펴보자.

Controller.h 파일은 다음과 같을 것이다:
#import
#import
@interface Controller : /* Specify a superclass (eg: NSObject or NSView) */
{
IBOutlet UIButton *decreaseButton;
IBOutlet UIButton *increaseButton;
IBOutlet UILabel *numberOfSidesLabel;
}
- (IBAction)decrease;
- (IBAction)increase;
@end


Objective-C는 C, C++, Java를 경험한 사람에게도 좀 특이하게 느껴질수 있다.
이전 강의를 통해 이것이 유저정의 클래스라는것을 알수 있지만 인터페이스 빌더로 부터 만들었기때문에
여기서는 아직 어떤 클래스를 계승받았는지 확정되어있지 않다.
슈퍼 클래스로서 NSObject를 지정하자.
@interface Controller : NSObject {


여기서 또한 우리가 지정한 outlet도 볼수 있는데 이는 인스턴스 변수로서 지정되어 있다. (UIButton * - 버튼에 대한 포인터)
런타임 실행시에 nib 파일이 로딩될 때 이 인스턴스 변수들은 우리가 인터페이스 빌더에서 설정한 연결에 따라 필요한 값을 갖게 된다.
즉, 오브젝트에게 메세지를 전달 할 수 있다는 뜻이다.

그러면 IBOutlet 키워드는 무슨 뜻일까.
IBOutlet 는 단순히 Interface Builder에게 주는 힌트이다.
이 인스턴스 변수들이 IB의 Connections Inspector에 표시 되어야 한다는 뜻이다.
이것은 컴파일 시에는 아무 의미 없는 키워드이다. (#defined를 살펴보면 아무것도 정의되어 있지 않다.)

여기에 increase 와 decrease 메소드도 정의되어 있는데 이것 또한 IBOutlet과 비슷한 IBAction 키워드가 사용된다.
이것은 이 메소드가 IB에서 target-action 연결을 설정할때 action메소드로서 표시되어야 한다는 뜻이다.
void의 동의어이다. Xcode에서 IBOutlet이나 IBAction을 더블클릭해보면 정의를 볼 수 있다.


다음은 Controller.m 을 열어보자:


Tip: 헤더파일과 implementation 파일사이를 점프할때는 오른쪽위의 아래와 같은 버튼(Go To Counterparts)을
누르면 번갈아가며 이동할 수 있다.
또한 메뉴의 Xcode > Preferences… > General > Open counterparts 를 이용하여 각기 다른 에이터 창이 아닌
하나의 에디터 창에서 번갈아가며 표시되도록 설정할 수 있다.


#import "Controller.h"
@implementation Controller
- (IBAction)decrease {
}
- (IBAction)increase {
}
@end


.m 파일에는  increase/decrease 액션 메소드에 대한 stub가 포함되어 있다.
인터페이스 빌더에서 버튼의 타겟으로 컨트롤러 오브젝트를 설정하였고 액션으로 이 메소드들이 설정되었다.
버튼이 클릭되었을때는 컨트롤러 오브젝트의 메소드가 실행 될 것이다.


중간점검: 로그, 빌드와 테스트

increase/decrease 메소드를 구현하기 전에 중간점검을 해보자.
각 메소드에 간단한 로깅을 적어 실행해본다.
NSLog(@“I’m in the increase method”);


버튼을 누르고 제대로 찍히는지 Run > Console에서 확인해 보자.

만약 여기서 제대로 동작하지 않는다면 인터페이스빌더의 target/action설정을 확인해 보도록 하라. (제일 틀리기 쉬운곳)


MVC모델의 M 구현하기

여기까지 우리는 MVC모델의 V와 C를 구현해 왔다. V는 인터페이스 빌더에서 만든 유저 인터페이스 였으며
C는 nib 파일에 정의된 컨트롤러 오브젝트이다.
컨트롤러는 outlet과 target/action을 통하여 뷰와 연결되어 졌다.
하지만 polygon은 어디에 위치해야 할까?
이것이 우리의 Model 부분이다. (M)

저번 과제에서 만든 Polygon 클래스를 사용한다.


Polygon 클래스를 Xcode 프로젝트에 추가한다:

1. Xcode의 메뉴에서 Project > Add to Project...를 선택한다.
2. Open 판넬에서 PolygonShape.h와 .m를 찾아 Shift키로 함께 선택한후 Add를 누른다.
3. 다음 창에서는 “Copy items into destination group’s folder (if needed)”를 체크하여 선택한 소스를 현재 프로젝트로 카피한다.


만약 체크하지 않는다면 외부 소스를 참조하기때문에 프로젝트를 이동하였을때 에러날 가능성이 있다.

여기서 polygon 오브젝트는 모델로 사용되기 때문에 다각형의 실제 정보를 담고 있다.
위에서 만든 컨트롤러는 유저 인터페이스를 업데이트 하기 위해 이 정보에 억세스 할수 있어야 하여
그러기 위하여 우리는 컨트롤러와 모델 사이의 연결을 확립시켜줘야 한다. 이부분이 다음 Task이다.


컨트롤러와 모델 사이의 연결 만들기

이 작업은 위에서 한 작업과 비슷하기 때문에 간단하게 순서만 나열해 보기로 한다.

1. Controller 클래스에 PolygonShape 타입의 인스턴스 변수를 선언한다.
(Controller.h 파일에 PolygonShape.h를 import해야 한다.)
인터페이스 빌더의 connections inspector에 나타나게 하기 위해서는 다른 인스턴스 변수들처럼 IBOutlet 키워드를 사용하여야 한다.

주의: IB를 기동하기 전에 Controller.h를 저장하지 않으면 connections inspector에 나타나지 않는다.

2. 새로운 유저정의 Object를 도큐먼트 윈도우에 추가한다. 클래스 명은 PolygonShape라고 준다.
(힌트: 이 과정은 Controller 클래스를 만든 방법과 동일하다.)

3. IB의 connections inspector 를 이용하여 PolygonShape 인스턴스와 Controller 인스턴스를 연결한다.


(힌트: connections inspector에 polygon outlet이 나타나있지 않는다면 Controller.h를 저장했는지 다시한번 확인해보라.)

4. nib파일을 저장한다.

중간점검: 빌드하고 실행하기

많은 작업을 해 왔기 때문에 여기서 이상이 없나 실행해본다.
이제 초기상태 설정과 increase/decrease 메소드를 구현하는 과정만 남았다.


초기상태 설정하기

초기상태를 설정하기 위해서는 polygon (다각형)의 최대값, 최소값, number of sides를 정하여 한다.
nib에서 자동 생성된 Controller와 Polygon 인스턴스에 값을 지정하기 위해서는 언제가 가장 좋은 시기인가.
우리는 두 오브젝트가 초기화 되고 Controller와 polygon의 연결이 성립된 타이밍을 알아야 하는데,
Cocoa Touch에서는 이 타이밍에 awakeFromNib라는 메소드가 불리도록 준비되어 있다.
nib의 모든 설정이 로딩되고 연결이 확립되면 각 오브젝트들의 awakeFromNib이라는 메소드가 호출된다.
유저정의 클래스에서 이 메소드를 구현하고 싶다면 여기에 원하는 작업을 아무거나 적어주면 된다.
이번 과제에서는 polygon 오브젝트의 최대/최소/number of sides를 적어줄 것이다.

awakeFromNib 메소드는 다음과 같이 적어주면 된다.

- (void)awakeFromNib {
// 여기에 polygon(다각형)을 정의한다.
}


최소/최대 값을 각가 3/12로 설정한다.
numberOfSides 를 설정하기 위해서는 UI의 text 라벨 값을 가져와야 한다.
awakeFromNib이 불리울때는 이미 모든 UI 요소들이 outlet으로 세팅 되어 있기 때문에 아래와 같은 소스로 불러올수 있다.
numberOfSidesLabel.text.integerValue


중간점검: Build and Run

중간 확인을 위해 awakeFromNib 메소드에서 polygon 오브젝트를 로그출력하여 number of sides값을 확인한다.
NSLog (@”My polygon: %@”, polygon);

Error: Cocoa/Cocoa.h No such file or directory. 라는 에러가 난다.

이유는 다른 프로젝트에서 카피해온 PolygonShape.h 에서 Cocoa.h를 import하고 있기 때문에.

저번 과제에서 잘 움직였는데 왜 여기서는?? 이라고 생각하며 검색해보니...

아이폰 어플리케이션에서는 cocoa.h를 import하지 않는다고 나온다.

cocoa.h의 import문을 빼고 컴파일하니 잘 된다. 이유는 나중에 나오겠지..


Action 메소드 구현

마지막 스텝은 increase/decrease 메소드를 구현하는 부분이다.
각 액션 메소드는 아래와 같은 방법으로 구현되어야 한다:

1. polygon의 number of sides를 가져온다.
2. number를 증가/감소 시킨다.
3. polygon에 증감시킨 새로운 number를 설정한다.
4. 새로운 상태를 유저 인터페이스에 적용한다.

4의 유저 인터페이스에 적용시키는 과정은 증/감 모두 같은 순서가 필요하다.
1. number of sides가 최소값에 다달았느냐 아니냐에 따라 decrease버튼을 비활성화 또는 활성화 시킨다.
2. number of sides가 최대값에 다달았느냐 아니냐에 따라 increase버튼을 비활성화 또는 활성화 시킨다.
3. number of sides의 현재 값을 text 라벨에 세팅한다.


이 부분은 여러 메소드에서 불리울수 있어야 하므로 아래와 같은 공통 메소드로 정의한다.

- (void)updateInterface {
// set interface state here
}


UI를 업데이트 하기 위한 힌트
• UIButton 을 활성화/비활성화 시키기 위해서는 “enabled” 속성을 사용하면 된다.
예: 버튼의 비 활성화
someButton.enabled = NO;

•“text” 속성을 이용하여 UILabel 값을 변경할 수 있다.
예: text 라벨에 숫자로 표시되는 문자값 표시하기.
someLabel.text = [NSString stringWithFormat:@”%d”, someNumber];

• UI의 초기상태를 설정하기 위하여 awakeFromNib에서도 같은 메소드를 사용하면 된다.


Build and Test
제대로 다 설정이 되었다면 시뮬레이터로 실행했을때 버튼을 눌러도 최소 3까지만 내려가고 최대 12까지만 올라갈 것이다.


Building for an iPhone or iPod touch
시뮬레이터에서 문제없이 돌아간다면 이제 실제 iPhone이나 iPod touch를 이용해본다.
개발자 프로그램에 등록되어 있다면(유료) Active SDK를 Device로 변경함으로써 간단히 인스톨/실행이 가능해진다.


디자인 리뷰

자, 우리는 MVC모델로 깔끔하게 디자인된 "진짜" iPhone 어플리케이션을 완성했다.
이 어플리케이션의 아키텍쳐와 지금까지 나온 용어들이 여기에 어떻게 들어맞는지 보기 위해 아래 다이어로그를 살펴본다.


완성된 Controller.m 소스

#import "Controller.h"

@implementation Controller

- (IBAction)decrease {

    NSLog(@"decrease method");

polygonObject.numberOfSides -= 1;

[selfupdateInterface];

}

- (IBAction)increase {

    NSLog(@"increase method");

    polygonObject.numberOfSides += 1;

[selfupdateInterface];

}

-(void)awakeFromNib {

polygonObject = [[PolygonShapealloc] initWithNumberOfSides:numberOfSidesLabel.text.integerValue minimumNumberOfSides:3maximumNumberOfSides:12];

NSLog(@"My polygon is: %@", polygonObject);

}

-(void) updateInterface {

if ([polygonObjectnumberOfSides] == [polygonObjectminimumNumberOfSides]) {

decreaseButton.enabled = NO;

} else {

decreaseButton.enabled = YES;

}

if ([polygonObjectnumberOfSides] == [polygonObjectmaximumNumberOfSides]) {

increaseButton.enabled = NO;

} else {

increaseButton.enabled = YES;

}

numberOfSidesLabel.text = [NSStringstringWithFormat:@"%d",[polygonObject numberOfSides]];

}

@end




출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10076311904
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 17:54
과제A - 클래스 생성과 사용

Lecture2 의 숙제에 대한 설명 또한 Lecture3 에서 주어지는것 같다. 쉬운 답을 얻기전에 검색해서 풀어보란 뜻인가??

아무튼 그냥 순서대로 Lecture3을 듣지 않은 상태에서 Lecture2의 숙제를 하기로 한다.


과제A. 클래스 생성과 사용  원문: WhatATool (Part II)


<순서>
Section 5. 클래스 생성
Section 6. 생성한 클래스 사용


이번 과제에서는 PolygonShape(다각형) 클래스를 생성한후 WhatATool의 메인 함수에서 클래스를 호출하는 함수를 불러본다.


아래와 같은 소스가 추가 될 것이다.


int main (int argc, const char * argv[]) {
    NSAutoreleasepool * pool = [[NSAutoreleasePool alloc] init];

    PrintPathInfo(); // Section 1
PrintProcessInfo(); // Section 2
PrintBookmarkInfo(); // Section 3
PrintIntrospectionInfo(); // Section 4
PrintPolygonInfo(); // Section 6 (section 5는 메인에 함수를 추가하지 않는다)
[pool release];
return 0;
}


Section 5. 클래스 생성

■ 새로운 PolygonShape 라는 클래스 만들기 (다각형 클래스)


Xcode에서
1.File > New File을 선택
2.Mac OS X아래 CoCoa 섹션의 'Objective-C class' 템플렛을 선택한다.
3.PolygonShape.m 으로 생성한다. - 헤더파일을 만들기 위한 체크박스를 체크하는 것을 잊지 말것.


* 새로운 클래스는 디폴트로 NSObject를 계승받는다.


자 이제 새로운 클래스에 속성을 부여해보자.
Objective-C 2.0은 오브젝트의 속성에 접근하는 새로운 메커니즘을 제공한다.
클래스는 "properties"를 정의 할 수 있으며, 이것이 유저가 클래스에 억세스 하는 방법을 제공한다.
properties는 개발자의 단순작업(getter/setter 코딩)을 없애주며 메모리 관리 폴리시와 속성의 사용법을 정의하도록 해준다.
예를 들면, property를 읽기 전용으로 지정하거나 오브젝트의 소유권등을 정의할 수 있다.


■ PolygonShape 클래스에 속성 지정하기


1. 아래의 속성을 지정한다.
• numberOfSides(면의 수) – 정수형
• minimumNumberOfSides(최소 면의 수) – 정수형
• maximumNumberOfSides(최소 면의 수) – 정수형
• angleInDegrees(내각) – 실수형, 읽기전용
• angleInRadians(호도) – 실수형, 읽기전용
• name(이름) – NSString 오브젝트, 읽기전용


2. numberOfSides, minimumNumberOfSides, maximumNumberOfSides의 세가지 속성은
적절한 타입의 인스턴스 변수로 저장될 수 있어야 한다. 이 속성들은 @synthesize 옵션을 이용하면 컴파일러가
자동으로 getter/setter를 생성하여주며, 읽기 전용 속성은 getter만이 생성된다.


3. setter 메소드에 아래와 같은 조건을 부여하라
• numberOfSides – 최소값과 최대값의 사이 값만 가질수 있다.
• minimumNumberOfSides – 2보다 커야 한다.
• maximumNumberOfSides – 12보다 작아야 한다.


maximumNumberOfSides에 5가 설정되어 있는데 numberOfSides에 9를 세팅하려고 한다면 아래와 같은 에러로그를 출력하라.
Invalid number of sides: 9 is greater than the maximum of 5 allowed


4. 아래와 같은 초기화 메소드를 생성하라.
- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;


5. 슈퍼클래스인 NSObject의 init메소드를 오버라이드 하여 아래와 같은 디폴트값을 설정하는 커스텀 init을 생성하라.
numberOfSides – 5, minimumNumberOfSides – 3, maximumNumberOfSides – 10


6. angleInDegrees와 angleInRadians는 @synthesize 옵션을 사용하지 말라.
그리고 인스턴스 변수도 불필요하다. 이 두 속성은 numberOfSides의 값에 의해 결정될 것이다.
여기서는 정규 다각형(regular polygon)만 만들것임으로 각도(angles)의 값은 모두 똑같을 것이다.


7. name속성도 @synthesize 옵션을 사용할 필요가 없다. (인스턴스 변수도 필요없다.)
면의 갯수로부터 다각형의 이름을 출력하게 될 것이다.
<예>
면이 3일 경우: “Triangle”
면이 4일 경우: “Square”


8. PolygonShape 클래스의 -description 메소드를 아래 예와 같이 나오도록 구현하라.
Hello I am a 4-sided polygon (aka a Square) with angles of 90 degrees (1.570796 radians).


9. dealloc메소드를 사용하여 메모리 관리를 하고, dealloc이 불리워졌을때 로그를 출력하도록 하여라.


<힌트>


•다각형의 이름은 위키에서 찾을 수 있다.
•내각(angleInDegrees)을 구하기 위한 식은 다음과 같다. (180 * (numberOfSides - 2) / numberOfSides)
•삼각법(trigonometry): 360° 는 2π(파이) 이다.
•π(파이)의 값은 M_PI에 정의되어 있다.

Section 6. 생성한 클래스 사용

WhatATool.m 파일에 #import "PolygonShape.h" 를 삽입한다.


중요!!! 여기서는 PolygonShape를 생성하기 위해 +alloc과 -init을 사용하도록 한다. 생성된 오브젝트는 배열에 넣도록 하고
사용이 끝난 후엔 메모리 관리 기술을 이용하여 오브젝트를 릴리스 하도록 한다.


1. alloc/init를 사용하여 mutable array를 생성하라.


2. 아래 값을 사용하여 3개 또는 그 이상의 PolygonShape 오브젝트를 생성하라.

Min number of sides Max number of sides Number of sides
 3  7  4
 5  9  6
 9  12  12

3. 생성한 오브젝트를 배열에 추가하고 description을 이용하여 로그를 출력하라. 최소한 3줄의 로그가 찍여야 한다.

4. polygon 오브젝트의 제약을 테스트 해본다.
루프를 돌며 numberOfSides에 10을 세팅해보라. 위의 테이블을 이용해 만든 오브젝트라면 두줄의 로그가 찍힐것이다.

5. polygon 오브젝트가 메모리로부터 릴리스 되었는지 확인한다.
주어진 규칙대로 생성한 클래스라면 dealloc이 불리면서 3번의 로그가 찍힐 것이다.


<시도>

우선 name의 getter를 구현하기 위해 다각형의 이름을 찾아봤다.

Polygon names

Name Edges
digon 2
triangle (or trigon) 3
quadrilateral (or quadrangle or tetragon) 4
pentagon 5
hexagon 6
heptagon 7
octagon 8
enneagon (or nonagon) 9
decagon 10
hendecagon 11
dodecagon 12

<구현한 소스>

PolygonShape.h +-----+-----+-----+-----+-----+

//

//  PolygonShape.h

//  WhatATool

//

//  Created on 09. 12. 14.

//  Copyright 2009 __MyCompanyName__. All rights reserved.

//

#import

@interface PolygonShape : NSObject {

intnumberOfSides;

intminimumNumberOfSides;

intmaximumNumberOfSides;

}

@propertyintnumberOfSides;

@propertyintminimumNumberOfSides;

@propertyintmaximumNumberOfSides;

@property (readonly) float angleInDegrees;

@property (readonly) float angleInRadians;

@property (readonly) NSString *name;

//헤더에 이 메소드를 추가하는걸 까먹어서 에러가 났었다.

- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;

@end

PolygonShape.m +-----+-----+-----+-----+-----+

//

//  PolygonShape.m

//  WhatATool

//

//  Created on 09. 12. 14.

//  Copyright 2009 __MyCompanyName__. All rights reserved.

//

#import "PolygonShape.h"

@implementation PolygonShape

@synthesize numberOfSides;

@synthesize minimumNumberOfSides;

@synthesize maximumNumberOfSides;

//synthesize선언한변수지만 setter존재하면 getter생성됨으로마음놓고써도된다.

-(void)setNumberOfSides:(int)newNumberOfSides {

    //numberOfSides최소값과최대값의사이값만가질수있다

    if(newNumberOfSides > maximumNumberOfSides) {

        //maximumNumberOfSides 5설정되어있는데 numberOfSides 9세팅하려고한다면에러로그를출력하라.

        NSLog(@"Invalid number of sides: %d is greater than the maximum of %d allowed", newNumberOfSides, maximumNumberOfSides);

    } elseif (newNumberOfSides < minimumNumberOfSides) {

        NSLog(@"Invalid number of sides: %d is less than the minimum of %d allowed", newNumberOfSides, minimumNumberOfSides);

    } else {

        numberOfSides = newNumberOfSides;

    }

}

//minimumNumberOfSides 2보다커야한다.

-(void)setMinimumNumberOfSides:(int)newMinimumNumberOfSides {

    if (newMinimumNumberOfSides < 2) {

    NSLog(@"Invalid minumum number of sides: %d is less than 2 allowed", newMinimumNumberOfSides);

} else {

    minimumNumberOfSides = newMinimumNumberOfSides;

}

}

//maximumNumberOfSides 12보다작아야한다.

-(void)setMaximumNumberOfSides:(int)newMaximumNumberOfSides {

    if (newMaximumNumberOfSides > 12) {

NSLog(@"Invalid maximum number of sides: %d is greater than 12 allowed", newMaximumNumberOfSides);

} else {

maximumNumberOfSides = newMaximumNumberOfSides;

}

}

//4. 초기화메소드를생성하라.

//주의! numberOfSides를 Max Min보다 먼저 세팅하려고 Max Min값이 0으로 인식되어 조건에서 튕겨나간다.

-(id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max {

[selfsetMinimumNumberOfSides:min];

[selfsetMaximumNumberOfSides:max];

[selfsetNumberOfSides:sides];

returnself;

}

//5. 슈퍼클래스인 NSObject init메소드를오버라이드하여아래와같은디폴트값을설정하는커스텀 init생성하라.

-(id)init {

if (self = [superinit]) {

    self = [selfinitWithNumberOfSides:5minimumNumberOfSides:3maximumNumberOfSides:10];

}

returnself;

}

//내각

-(float)angleInDegrees {

return (180 * (self.numberOfSides - 2) / self.numberOfSides);

}

//라디안

-(float)angleInRadians {

returnM_PI / 180 * self.angleInDegrees;

}

//7. 면의갯수로부터다각형의이름을출력하게것이다.

-(NSString *)name {

    switch ([selfnumberOfSides]) {

case2: return@"digon"; break;

case3: return@"triangle"; break;

case4: return@"quadrilateral"; break;

case5: return@"pentagon"; break;

case6: return@"hexagon"; break;

case7: return@"heptagon"; break;

case8: return@"octagon"; break;

case9: return@"enneagon"; break;

case10: return@"decagon"; break;

case11: return@"hendecagon"; break;

case12: return@"dodecagon"; break;

default: return@"";

}

}

//8. description오버라이드

//: Hello I am a 4-sided polygon (aka a Square) with angles of 90 degrees (1.570796 radians).

-(NSString *)description {

return [NSStringstringWithFormat: @"Hello I am a %d-sided polygon (aka a %@) with angles of %.0f degrees (%.6f radians)."

self.numberOfSides, self.name, self.angleInDegrees, self.angleInRadians];

}

//9. dealloc메소드를사용하여메모리관리를하고, dealloc불리워졌을때로그를출력하도록하여라.

- (void)dealloc {

NSLog(@"dealloc called");

[superdealloc];

}

@end

WhatATool.m의 함수(Section 6) 부분 +-----+-----+-----+-----+-----+

//#import "PolygonShape.h" 를 잊지말자


//Section 6

void PrintPolygonInfo() {

    NSLog(@"----- Section 6 -----");


    //배열 생성

NSMutableArray *array = [[NSMutableArrayalloc] init];

PolygonShape *polygon1 = [[PolygonShapealloc] initWithNumberOfSides:4minimumNumberOfSides:3maximumNumberOfSides:7];

PolygonShape *polygon2 = [[PolygonShapealloc] initWithNumberOfSides:6minimumNumberOfSides:5maximumNumberOfSides:9];

PolygonShape *polygon3 = [[PolygonShapealloc] initWithNumberOfSides:12minimumNumberOfSides:9maximumNumberOfSides:12];

    //생성한 다각형 정보를 로그에 출력하고 배열에 다각형 오브젝트를 추가한다.

NSLog([polygon1 description]);

[array addObject:polygon1];

NSLog([polygon2 description]);

[array addObject:polygon2];

NSLog([polygon3 description]);

[array addObject:polygon3];

//제약을 테스트하기 위해 numberOfSides에 10을 넣어본다.

for (PolygonShape *polygon in array) {

polygon.numberOfSides = 10;

}

[polygon1 dealloc];

[polygon2 dealloc];

[polygon3 dealloc];

[array dealloc];

}

<결과>

2009-12-17 14:54:31.297 WhatATool[1125:10b] ----- Section 6 -----

2009-12-17 14:54:31.297 WhatATool[1125:10b] Hello I am a 4-sided polygon (aka a quadrilateral) with angles of 90 degrees (1.570796 radians).

2009-12-17 14:54:31.297 WhatATool[1125:10b] Hello I am a 6-sided polygon (aka a hexagon) with angles of 120 degrees (2.094395 radians).

2009-12-17 14:54:31.297 WhatATool[1125:10b] Hello I am a 12-sided polygon (aka a dodecagon) with angles of 150 degrees (2.617994 radians).

2009-12-17 14:54:31.298 WhatATool[1125:10b] Invalid number of sides: 10 is greater than the maximum of 7 allowed

2009-12-17 14:54:31.298 WhatATool[1125:10b] Invalid number of sides: 10 is greater than the maximum of 9 allowed

2009-12-17 14:54:31.298 WhatATool[1125:10b] dealloc called

2009-12-17 14:54:31.299 WhatATool[1125:10b] dealloc called

2009-12-17 14:54:31.299 WhatATool[1125:10b] dealloc called

The Debugger has exited with status 0.



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10076162791
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 17:53
과제B.4 - Selector 의 이용과 클래스 정보 보기

[과제B Section 4] Selector 의 이용과 클래스 정보 보기


지금까지 만들어봤던 NSString, NSURL, NSProcessInfo, NSDictionary 등과 NSMutableString을 인스턴스화해서
배열(NSMutableArray)에 넣어라.


그리고 아래를 수행하라.


1. 오브젝트의 클래스명을 출력하라
2. 오브젝트가 NSString 클래스인지 출력하라
3. 오브젝트가 NSString의 서브클래스인지 출력하라
4. 오브젝트가 "lowercaseString"를 지원하는지 출력하라
5. "lowercaseString"를 지원하는 오브젝트라면 performSelector:를 이용하여 결과를 출력하라


<예상하는 결과 형식>

2008-01-10 20:56:03 WhatATool[360] Class name: NSCFString
2008-01-10 20:56:03 WhatATool[360] Is Member of NSString: NO
2008-01-10 20:56:03 WhatATool[360] Is Kind of NSString: YES
2008-01-10 20:56:03 WhatATool[360] Responds to lowercaseString: YES
2008-01-10 20:56:03 WhatATool[360] lowercaseString is: hello world!
2008-01-10 20:56:03 WhatATool[360] ======================================
2008-01-10 20:56:03 WhatATool[360] Class name: NSURL
2008-01-10 20:56:03 WhatATool[360] Is Member of NSString: NO
2008-01-10 20:56:03 WhatATool[360] Is Kind of NSString: NO
2008-01-10 20:56:03 WhatATool[360] Responds to lowercaseString: NO
2008-01-10 20:56:03 WhatATool[360] ======================================
2008-01-10 20:56:03 WhatATool[360] Class name: NSCFDictionary
2008-01-10 20:56:03 WhatATool[360] Is Member of NSString: NO
2008-01-10 20:56:03 WhatATool[360] Is Kind of NSString: NO
2008-01-10 20:56:03 WhatATool[360] Responds to lowercaseString: NO
2008-01-10 20:56:03 WhatATool[360] ======================================


<힌트>
아마도 NSString과 같은 클래스 명이 예상치 않은 결과가 나올수 있지만
그건 implementation의 문제이니 여기선 그냥 넘어가도록 한다.


<실습>
NSString, NSURL, NSProcessInfo, NSDictionary, NSMutableString을 만든다.


NSString *myString = @"Hello World!";
NSURL *myURL = [NSURL URLWithString:@"
http://www.stanford.edu"];
NSProcessInfo *myProcess = [NSProcessInfo processInfo];
NSDictionary *myDictionary = [NSDictionary dictionary];
NSMutableString *myMutableString = @"This is a mutable string object";


NSMutableArray를 만들고 위의 오브젝트들을 추가한다.


NSMutableArray *array = [NSMutableArray array];
[array addObject:myString];
[array addObject:myURL];
[array addObject:myProcess];
[array addObject:myDictionary];
[array addObject:myMutableString];


루프를 돌며 클래스 정보를 출력한다.


■ 오브젝트의 클래스명을 출력하라


모든 오브젝트는 NSObject를 계승하니까... NSObject reference를 찾아보자.

- (NSString *)description 이라고 하니까, 클래스 설명이 나와버린다.

구글 검색을 해보니까 className을 쓰면 된다고 한다.

[obj className];

왜 NSObject의 리퍼런스에 나와있지 않은지 모르겠지만 아마도 다른 연관이 있는듯. 일단 나오니까 스킵.


 오브젝트가 NSString 클래스인지 출력하라
- (BOOL)isMemberOfClass:(Class)aClass 이용


오브젝트가 NSString의 서브클래스인지 출력하라
- (BOOL)isKindOfClass:(Class)aClass 이용


오브젝트가 "lowercaseString"를 지원하는지 출력하라
- (BOOL)respondsToSelector:(SEL)aSelector 이용


"lowercaseString"를 지원하는 오브젝트라면 performSelector:를 이용하여 결과를 출력하라
- (id)performSelector:(SEL)aSelector 이용

Selector 란 컴파일된 오브젝트의 메소드를 가르키는 이름이라고 한다.

즉, performSelector: 같은 메소드에 Selector를 지정함으로써 실행할수 있다는 뜻이다.

<결과>

성공!!!



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10075791909
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 17:53
과제B.3 - 즐겨찾기 만들어보기 (NSMutableDictionary 클래스 이용)

[과제B Section 3] 즐겨찾기 만들어보기 (NSMutableDictionary 클래스 이용)

아래의 값으로 NSMutableDictionary를 생성한다.

Key (NSString) Value (NSURL)
Stanford University http://www.stanford.edu
Apple http://www.apple.com
CS193P http://cs193p.stanford.edu
Stanford on iTunes U http://itunes.stanford.edu
Stanford Mall http://stanfordshop.com

루프를 돌다가 Stanford로 시작하는 키를 가진 값이 있으면 아래와 같이 로그를 출력한다.


Key: 'Stanford University' URL: 'http://www.stanford.edu'


<조건 및 힌트>
+URLWithString: 을 이용하여 URL 인스턴스를 생성하라.
NSString의 prefix/suffix를 체크하는 메소드를 이용하라.
NSMutableDictionary 는 NSDictionary의 서브클래스임을 기억하라.


NSMutableDictionary를 생성하기 위해 리퍼런스를 보자.

클래스 메소드에 dictionaryWithCapacity: 밖에 없으니... 슈퍼클래스인 NSDictionary의 클래스 메소드를 살펴본다.

dictionary라는 빈 딕셔너리를 생성해주는 클래스 메소드를 찾았다.


이용해 본다.

NSMutableDictionary *myDictionary = [NSMutableDictionary dictionary];


키와 값을 추가한다.


<시도 1>

- (void)setObject:(id)anObject forKey:(id)aKey 을 이용해 본다.


[myDictionary setObject:[NSURL URLWithString:@"http://www.stanford.edu"] forKey:@"Stanford University"];
[myDictionary setObject:[NSURL URLWithString:@"
http://www.apple.com"] forKey:@"Apple"];
[myDictionary setObject:[NSURL URLWithString:@"
http://cs193p.stanford.edu"] forKey:@"CS193P"];
[myDictionary setObject:[NSURL URLWithString:@"
http://itunes.stanford.edu"] forKey:@"Stanford on iTunes U"];
[myDictionary setObject:[NSURL URLWithString:@"
http://stanfordshop.com"] forKey:@"Stanford Mall"];


<결과>
일단 컴파일 에러가 안나니까 성공.

계속해서 Stanford로 시작하는 키의 정보를 로그로 출력해 보자.

NSDictionary의 - (NSArray *)allKeys 를 이용해 본다.


for (NSString *element in [myDictionary allKeys] ) {
    NSLog(element);
}


■ 그럼 스트링이 특정 문자로 시작하는지 알아보는 메소드는?


혹시 prefixWith.. 라는 메소드가 있나 했는데 없다. 음...


NSString Class Reference의 COMPANION GUIDES에 나와있는 String Programming Guide for Cocoa을 열어 봤다.

문서내의 Searching, Comparing, and Sorting Strings를 참조.

검색 메소드중 rangeOfString:options: 이라는게 있는데 이 옵션을 살펴보니 아래와 같은 내용이 있다.

검색 옵션 효과
NSAnchoredSearch Performs searching only on characters at the beginning or end of the range. No match at the beginning or end means nothing is found, even if a matching sequence of characters occurs elsewhere in the string.


NSString의 처음이나 끝에 검색하고자 하는 스트링이 있는지 찾아본다. 중간에 있는건 무효.

<시도>    
NSRange prefixRange = [key rangeOfString:@"Stanford" options:NSAnchoredSearch)];


리턴값은 NSRange인데 rangeOfString:options: 메소드의 설명을 보면 아래와 같다.

Return Value
An NSRange structure giving the location and length in the receiver of the first occurrence of aString, modulo the options in mask. Returns {NSNotFound, 0} if aString is not found or is empty (@"").

즉, 값을 찾지 못했을경우에는 {NSNotFound, 0} 가 돌아온다고 한다.


NSRange는 아래와 같은 구조체 이니까,

typedef struct _NSRange {
   NSUInteger location;
   NSUInteger length;
} NSRange;


location이 NSNotFound인지 살펴보면 될 것 같다.

if ([element rangeOfString:@"Stanford" options:NSAnchoredSearch].location != NSNotFound) {
    로그출력...
}


<결과>
성공!!!



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10075724258
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 17:53
과제B.2 - 프로세스 ID 찍어보기 (NSProcessInfo 클래스 이용)

[과제B Section 2] 프로세스 ID 찍어보기 (NSProcessInfo 클래스 이용)

NSProcessInfo 를 이용하여 아래와 같이 프로세스명, 프로세스ID를 출력하라

Process Name: 'WhatATool' Process ID: '4556'


클래스 리퍼런스를 참조하니 processNameprocessIdentifier라는 그럴듯한 메소드가 있다.


<시도 1>

NSProcessInfo *pInfo = [NSProcessInfo processInfo];

NSLog(@"Process Name: '%@' Process ID: '%@'", [pInfo processName], [pInfo processIdentifier]);


<결과>

실패.... 컴파일 에러는 안나지만 프로그램 시작후 이상한 메세지가 뜬 상태로 안끝난다...


<시도 2>

프린트할 ID부분의 포멧을 %@ (오브젝트) 에서 %i (정수형)으로 바꿔봤다.

NSLog(@"Process Name: '%@' Process ID: '%i'", [pInfo processName], [pInfo processIdentifier]);


<결과>

성공!!!



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10075722816
Posted by 오늘마감

댓글을 달아 주세요