아이폰어플개발정보2010. 9. 11. 01:33
완성된 아이폰 어플 앱스토어에 올리는 절차

안녕하세요 문씨입니다.
저번에 줄줄이 쓸때 올릴만한 완성된 어플이 없어서 그만 빼먹었었네요;;;
어플을 스토어로 올리기위해서는 크게 두군데에서 준비를 해야합니다. 
하나는 담당 사이트인 아이튠스 코넥트에서 올릴 어플의 정보를 설정하는것이고
다음은 올릴 어플을 준비하는 것입니다.
 먼저 어플을 준비해보겠습니다.
키체인에 배포용 키가 설치되어 있어야 합니다 (http://cafe.naver.com/mcbugi/8953)
먼저 개발자 포탈 사이트에서 배포용 프로비션 프로파일을 만듭니다.
물론 미리 App ID는 만들어 둡니다. (http://cafe.naver.com/mcbugi/8964)
포탈 메뉴에서 Provisioning 메뉴로 들어가서 Distribution 탭으로 들어갑니다.
New Profile을 클릭해서 새로 하나 만듭니다.
올리는 어플 하나당 프로파일이 하나씩 필요합니다.
Profile Name에 어플 이름을 적고
AppID 에서 만든 앱 아이디를 선택합니다
그리고 Submit을 클릭해서 완료합니다
잠시 기다렸다가 새로고침해서 만들어진 프로파일을 다운로드 합니다.
다운 받은 프로파일을 실행해서 설치합니다.
여기까지는 애드훅 설치법과 비슷합니다. (http://cafe.naver.com/mcbugi/9042)
이제 xCode에서 배포할 어플 프로젝트를 엽니다.
info.plist 파일에서 Bundle identifier항목에 만든 AppID를 동일하게 씁니다.
새파일 만들기로 Entitlements.plist파일을 만듭니다.
Adhoc에서는 내용에서 채크를 뺏지만 여기서는 그냥 놔둡니다.
이번에는 프로젝트 설정으로 갑니다. (프로젝트 부분 더블 클릭)
Configurations탭에서 Release를 선택한후 하단에 Duplicate를 클릭합니다.
그리고 새로 만들어진 것을 Distribution으로 이름을 바꿔줍니다
Build탭으로 갑니다
Configuration항목을 Distribution으로 바꾼뒤 Code Signing부분을 봅니다
먼저 Code Signing Entitlements를 수정합니다
아까 만든 파일명을 그대로 적어줍니다
 
Code Signing Identity와 바로 아래 두곳을 맞는 AppID에 찾아서 선택합니다
보통 iPhone Distribution: 이름 및 회사명으로 되어 있습니다
빌드 메뉴에서 Device로 선택하고 버전을 맞춘뒤 항목을 Distribution으로 맞춥니다
CMD + B나 빌드 메뉴에 빌드로 빌드해줍니다.
그럼 Products에 어플.app가 있는것을 볼수 있습니다
항목을 오른쪽 클릭해서 나오는 메뉴에서 Reveal in Finder명령으로 해당 파일의 위치를 엽니다
파인더에서 파일이 두개가 보입니다.
dSYM은 빼고  해당 어플만 압축합니다..
여기까지 파일 준비는 되었습니다
이제는 아이튠스 코넥트에서 올릴 어플 정보를 씁니다
아이튠스 코넥트로 들어갑니다 (https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa)
Manage Your Applications 항목으로 갑니다
 Add New Applicatioin메뉴를 클릭해서 새로 어플 추가를 합니다
어플의 암호화 관련 질문입니다 NO로 하고 다음으로 넘어갑니다
Application Name: 올릴 어플의 이름입니다.
Application Description: 설명을 적습니다
Device Requirements: 지원 기기입니다. iPhone and iPod Touch가 모든 기기 지원이라 보면 됩니다.
다음 두개는 카테고리 선택입니다. 
Copyright은 적당히 저작권 정보를 씁니다 예) smoon.kr 2009 등등;;;
Version Number: 버전 번호 입니다 보통 1.0
SKU Number: 자세히는 모르지만 지신이 구별할 어플 실별 코드라고 보면 됩니다. 전 보통 AppID를 사용합니다
Keywords 검색어 입니다 (전엔 없었는데;;;)
Application URL: 어플 소개 홈피 주소입니다.
Support URL: AS를 위한 사이트 주소입니다
다음은 연락처 이멜 주소입니다
Demo Account: 어플의 종류에 따라서 로그인 인증이 필요한 것도 있습니다.  이럴경우 미리 만들어서 적어줘야 합니다. 심사의원이 따로 가입까지는 안합니다;;; 게임의 경우 테스트용도의 아이디를 대줘야 합니다.
다음  하단의 Continue를 클릭해서 넘어갑니다
등급 설정입니다. 거의 게임이나 폭력성 어플에 해당합니다
적당히 판단하에 선택합니다
다음으로 넘어가면 파일 올리기입니다
Application에 아까 만들어둔 압축파일을 올립니다. 올리는데 시간이 좀 걸리고
다 올라가면 검사도 하기 때문에 에러가 날경우 어딘가 인증 작업을 잘못 했거나 아이콘이 규격에 안맞거나 등등 
원인을 메세지를 알려줍니다.
Large 512...는 대형 아이콘 파일입니다.  JPEG형식에 크기 512 픽셀 정사각형의 이미지를 준비해서 올립니다.
앱스토어에 뜨는 아이콘은 이 파일입니다. 실제 앱 아이콘과 전혀 틀리면 리젝의 원인이 되기도 합니다.
Primary Screenshot 기본 스샷입니다 JPEG로 320 x 480크기만 됩니다
나머지는 추가 스샷으로 기본 스샷과 같은 조건이면 최대 4개 까지 올릴수 있습니다
다 올리면 다음으로 넘어갑니다
가격 설정입니다.
원하는 가격을 설정후 앱스토어에 올라갈 날자를 정합니다 보통 일주일에서 10일 정도 걸리 대충 그 이후로 정합니다.
언어 선택입니다. 그냥 넘어갑니다.
(너무 대충;;;)
마지막으로 적은 정보를 확인뒤 Submit Application을 클릭해서 완료 합니다



출처 : http://blog.naver.com/PostList.nhn?blogId=hana_815¤tPage=87
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 9. 11. 01:32
아이폰 어플 개발 Table View 의 기초

Table View Basics
iPhone tables(UITableView) 의 행(Row)수는 제한이 없음.(iPhone OS Memory)
UITableView - 테이블의 Data를 표시하는 뷰 오브젝트.
UITableViewCell - 테이블의 단일 행을 표현.

UITableViewCell 에 복수의 데이터를 추가하기 위해서
1.UITableViewCell 에 subview 를 추가 하거나
2.UITableViewCell 을 상속하는 서브클래스 작성.

Table > Section > Rows...
그룹 테이블(Figure 8-3)에서 각 Section 은 한 그룹을 나타냄.
인덱스 테이블(Figure 8-3)에서 각 Section 은 한 인덱스의 집합.

Implementing a Simple Table
Writing the Controller

  1. // delegate, datasource protocol 선언.
  2. // datasource 는 테이블 각 행에 대한 데이터 핸들.
  3. // delegate 는 데이터의 설정(font, user interation...) 핸들.
  4. @interface SomeUITableView  {  
  5.     // Table Data.
  6.     NSArray *tableData;  
  7.     ...  
  8. }  
  9. #pragma mark -
  10. #pragma mark Table View Data Source Methods
  11. // 해당 Section 에 행 수.
  12. - (NSInteger)tableView:(UITableView *)tableView  
  13.  numberOfRowsInSection:(NSInteger)section {  
  14.     return [self.tableData count];  
  15. }  
  16. // 행이 그려질 때 호출되어 현재 표시될 행의 UITableViewCell 를 리턴.
  17. // NSIndexPath 를 이용해서 해당 Section[indexPath section]과
  18. // 해당 행[indexPath row]을 알 수 있음.
  19. // UITableViewCell 는 캐쉬화 되고 시스템 메모리가 부족할 때 자동 메모리 해제됨.
  20. - (UITableViewCell *)tableView:(UITableView *)tableView  
  21.          cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
  22.     // cache 할 때 구분자.
  23.     static NSString *SomeID = @"SomeID";  
  24.     // cache 에 저장된 UITableViewCell 취득.
  25.     UITableViewCell *cell = [tableView   
  26.                              dequeueReusableCellWithIdentifier:SomeID];  
  27.     if (cell == nil) {  
  28.         cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero  
  29.                  reuseIdentifier:SomeID] autorelease];  
  30.     }  
  31.     ...  
  32. }  


Adding an Image
UITableViewCell 의 기본 옵션으로 각 행의 왼쪽에 이미지를 붙일 수 있음.
  1. // tableview:cellForRowAtIndexPath:
  2. ...  
  3. UIImage *image = [UIImage imageNamed:@"someImage.png"];  
  4. cell.image = image;  
  5. ...  


Addtional Configurations
Setting the Indent Level
  1. #pragma mark -
  2. #pragma mark Table View Delegate Methods
  3. // 각 행의 indent level(NSInteger) 설정.
  4. - (NSInteger)tableView:(UITableView *)tableView  
  5. indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {  
  6.     ...  
  7.     return indentLevel;  
  8. }  


Handling Row Selection
USER 가 선택한 행의 이벤트 전후로 핸들링이 가능.
  1. - (NSIndexPath *)tableView:(UITableView *)tableView  
  2.   willSelectRowAtIndexPath:(NSIndexPath *)indexPath {  
  3.     // USER 선택에 대한 이벤트 전처리.
  4.     ....  
  5. }  
  6. - (NSIndexPath *)tableView:(UITableView *)tableView  
  7.    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  
  8.     // USER 선택에 대한 이벤트 후처리.
  9.     ....  
  10. }  


Changing Font Size and Row Height
  1. // tableview:cellForRowAtIndexPath:
  2. ...  
  3. cell.font = [UIFont boldSystemFontOfSize:80];  
  4. ...  
  5. // 열의 높이 설정.
  6. - (CGFloat)tableView:(UITableView *)tableView  
  7. heightForRowAtIndexPath:(NSIndexPath *)indexPath {  
  8.     ....  
  9.     return height;  
  10. }  



출처 : http://blog.naver.com/PostList.nhn?blogId=hana_815¤tPage=91
Posted by 오늘마감

댓글을 달아 주세요

XCODE2010. 9. 6. 00:28
아이폰 어플 개발의 필수인 XCode에서 디버깅하는 방법

디버깅


Friday Section 은 원래 비공개 강의라서 동영상 강의가 없다. 단 2009년 버젼에서는 pdf가 제공됨으로 그걸 토대로 실습해 본다.


1.XCode 인터페이스 살펴보기 - 팁, 트릭(trick), 유용한 세팅
2.문서들 - 어떻게 찾나
3.좋은 디버깅 방법 - NSLog 외의 방법 살펴보기
4.디버깅 실습


1. XCode 인터페이스 살펴보기


- 연습문제를 다운로드 한다 -

맥 초보인 나로써는 다운받은 zip파일이 어디있나 한참 헤메이다가
Macintosh HD > 사용자 > XXX(유저명) > 다운로드 에 있다는 것을 발견. ㅡㅡ;
XCode 프로젝트로 옮기고 싶은데 이번엔 프로젝트 폴더가 어딨는지 몰라서 방황하다가
Macintosh HD > 사용자 > XXX(유저명) > 도큐먼트 에 있다는 것을 발견하고
힘들게 마우스로 끓어담겨 옮겼다. ㅡㅡ;;;

그래서 결국 최종 폴더는
Macintosh HD > 사용자 > XXX(유저명) > 도큐먼트 > Section-1-Exercises

■ XCode Walkthrough
•Splitter-working 프로젝트를 연다.


•프로젝트가 정상적으로 실행되는지 Build-and-Go를 해 본다. => 시뮬레이터가 기동되면서 Split 화면이 나오면 OK.


■ Splitter 데모에서 확인 해 볼 수 있는 기능들
•splitter가 어떻게 작동하는지 보여준다.
•추천하는 세팅:
    XCode->Preferences->Text Editing->Show line numbers (라인 번호 표시)

    XCode->Preferences->Text Editing->Show page guide (페이지 가이드 표시)

   


    XCode->Preferences->Debugging->On Start:->Show Console (콘솔 표시)
    XCode->Preferences->Debugging->On Start:->Auto Clear Debug Console (자동으로 디버깅 콘솔 클리어하기)

   


•심볼 셀렉터를 보여준다.


•툴바 유저정의

참고문헌 - Xcode Workspace Guide

2.문서들 - 어떻게 찾나


■ 어떻게 찾나
• 개발에 필요한 문서들은 Xcode안에 포함되어 있다
• 찾기 위한 두가지 방법
    Browse
    Search


■ 문서 검색 데모
•Browsing
    Help->Documentation
    Doc Sets->Apple iPhone OS 2.2.1->Subscribe
    “iPhone Reference Library” 페이지로 이동한다.
    왼쪽 트리메뉴를 이용하여 필요한 문서를 찾아내려간다.
    초보자에게 아주 유용한 문서들:
        “Getting Started”
        “Guides”
        “Sample Code”


•Search
    Browsing은 새로운 개념을 공부하고자 할때 유용하며, 검색은 코딩중에 문서를 보고 싶을때 유용하다.
    splitter-working 프로젝트로 돌아가서 Controller.m을 살펴보자.
    NSString위에서 ctrl+클릭(원버튼 마우스) 혹은 오른쪽 클릭을 하면 메뉴가 뜬다.

        -> Find Selected Text In API Reference 를 선택하면 리퍼런스가 열린다.

    

    결과 필터링: 툴바의 All Doc Sets 대신 Apple iPhone OS 3.1 Library 를 선택한다.

 

    결과 필터링: 툴바의 참조 API 언어 옵션에서 C 와 Obj C 만 남겨두고 나머지 언어는 체크를 없앤다.


    리퍼런스를 둘러보며 자바 API 리퍼런스와 비교해 본다.
    ctrl-F for capital
    splitter-working 프로젝트로 돌아와서 resignFirstResponder가 무엇을 하는 기능인지 알아보라.


3.좋은 디버깅 방법


■ 두가지 디버깅 방법


•그렇게 멋지지 않은 디버깅 방법: NSLog
    몇몇 상황에서는 유용할 수도 있다... 아마도.
    변수들을 직접 조사하는것 보다 훨씬 불편하다.


•멋진 방법: 디버거(Debugger)
    버그 수정을 위한 가장 좋은 방법
    브레이크 포인트를 설정 한 후, 코드를 한줄씩 실행하며 변수들을 조사한다.

4.디버깅 실습

■ NSLog
    Controller.m 을 연다.
    NSLog를 이용하여 textField.text 값을 찍는다.
    실행한다 (Build and go)
    콘솔에서 로그를 확인 한다.


    => 문제없이 값을 확인 할 수 있지만 쓸데없는 코드를 적어줘야 한다.


■ Debugger
    다음 코드 부분에 브레이크 포인트를 설정한다. NSString *string = textField.text;
    실행한다. (Build and go)
    브레이크 포인터 이후는 한줄 씩 실행(Step over) 한다.
    변수위에 마우스를 올려놓으면 값이 팝업으로 뜨게 된다.
    디버그 윈도우를 이용하여 값을 알아볼수 있다.

■ 혼자 실습해보기
•Warmup-working 프로젝트를 실행하여 무엇을 하는지 알아보라.
•Splitter-working 프로젝트를 실행하여 무엇을 하는지 알아보라.
•6가지 연습문제를 아래의 방법으로 풀어보라:
    1) 프로젝트에서 Run 또는 Go 대신 Debug 로 실행한다.
    2) 어떤 에러가 뜨는지 확인한다.
    3) 어디서 에러가 나는지 찾아본다.
    4) 에러를 수정한다.
    5) 왜 에러가 났는지 이해한다.


■ 6가지 연습문제에 대한 힌트
•Warmup-exercise1
    매우 간단하게 에러를 찾아내서 수정 할 수 있을 것이다.
•Warmup-exercise2
    힌트 1: 디버거 윈도우(debugger window)를 살펴보라.
    힌트 2: 마지막으로 출력된 메세지를 살펴보라.
•Warmup-exercise3
    힌트 1: 디버거 윈도우(debugger window)를 살펴보라.
    힌트 2: API를 찾아보라.
•Splitter-exercise1
    힌트: XCode 내에서는 문제를 수정 할 수 없을 것이다.
•Splitter-exercise2
    힌트: 디버거 윈도우(debugger window)를 살펴보라.
•Splitter-exercise3
    힌트 1: 에러 메세지는 도움이 안된다.
    힌트 2: 마지막 강의에서 나온 프로퍼티와 메모리 관리에 대해 생각해보라.


■ Mac OS X 주요 단축키
•Mac OS X 초보자를 위한 팁:
    -x/c/v: cut/copy/paste
        ※ => 명령키
    -Space bar: spotlight
        spotlight를 통해 어프리케이션 실행, 계산, 파일 검색이 가능하다.
    w: 현재 윈도우를 닫는다.
    q: 현재 어플리케이션을 닫는다.
    ~: 다른 윈도우로 이동한다. Windows의 Alt+Tab과 동일한 기능
    -Delete: 파일 삭제 (휴지통으로 이동)


■ XCode 주요 단축키
•XCode 초보자를 위한 팁:
    Esc: 자동 완성
        클래스나 메소드, 변수등을 입력할때 사용 가능하다.
        시험삼아 “[NSString “ 를 입력한후 Esc를 누르면 NSString에서 사용 가능한 메소드 일람이 표시된다.
    Enter: Build and Go
    /: 커멘트화 또는 비 커멘트화 시킨다.
    }: 오른쪽으로 들여쓰기 (Indent right)
    {: 왼쪽으로 들여쓰기 (Indent left)
    ↑: 헤더/소스 파일간을 이동한다.
        = 옵션키




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

댓글을 달아 주세요

아이폰 어플 개발, 모델, 뷰, 컨트롤러의 생성과 연동하는 방법



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


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 오늘마감

댓글을 달아 주세요

아이폰 어플 개발할때 클래스 생성과 사용하는 방법


<순서>
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 오늘마감

댓글을 달아 주세요

아이폰 어플 개발 , 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. 8. 30. 10:07
아이폰 어플 개발 , 사용자 홈 디렉토리 찍어보기 (NSString 클래스 이용)

[과제B Section 1] 사용자 홈 디렉토리 찍어보기 (NSString 클래스 이용)

NSString *path = @"~";
를 이용하여

My home folder is at '/Users/pmarcos'
를 출력하라.

또한 경로를 배열로 돌려주는 메소드를 이용하여 아래와 같이 출력하라.

/
Users
pmarcos


Objective-C의 NSString을 이용할땐 항상 @”Hello World” 와 같이 앞에 @를 붙여 주어야 한다.

NSString을 이용하여야 할 곳에 C의 String을 이용해 버리면 프로그램이 제대로 작동하지 않을수 있다.

■ NSString 클래스에 대한 정보는 어디에 있을까?

iPhone Dev Center 에 가면

iPhone Reference Library > Resource Types > Reference 를 열면 기본 클래스에 대한 문서들이 나오며 검색창이 보인다.
"NSString"이라고 치면 NSStringClass Reference 라는 링크를 볼 수 있다.
또한 설치한 Xcode의 Help > Documentation으로 가서 찾아도 된다.
■ 유저 홈 디렉토리란?
Mac OS는 유닉스베이스로 만들어져 있음으로 유저 홈 디렉토리는 "~"(틸드)로 표현이 가능하다.
스트링을 선언해 본다.
NSString *path = @"~";
<원하는 결과>
My home folder is at '/Users/pmarcos'
<시도1>
NSLog(@"My home folder is at %@", path);
* 여기서 %@란 Objective-C의 오브젝트를 의미한다. 자세히는 Format Specifiers 참조.
결과는 My home folder is at ~.
당연하다면 당연하지만, 혹시나 자동으로 바꿔주나 싶었다.
다시 NSString의 API Doc을 참조하여 이번엔 어떤 메소드가 있나 봤다.
틸드가 어쩌고 하는 메소드 발견.
내용은... 패스안에 틸드로 생략된 문자? ... 참 긴 이름이다.
stringByAbbreviatingWithTildeInPath

Returns a new string representing the receiver as a path with a tilde (~) substituted for the full path to the current user’s home directory.

- (NSString *)stringByAbbreviatingWithTildeInPath

Return Value

A new string representing the receiver as a path with a tilde (~) substituted for the full path to the current user’s home directory. Returns a new string matching the receiver if the receiver doesn’t begin with a user’s home directory.

어쨋든 틸드 대신 스트링으로 유저홈을 돌려주나보다.

<시도2>

NSLog(@"My home folder is at %@", [path stringByAbbreviatingWithTildeInPath]);

<결과>
성공!!!
 
■ 경로를 배열로 취득하기
 
NSString 클래스 리퍼런스 문서를 더 찾아보니 pathComponents라는 인스턴스 메소드가 존재한다.
리턴값은 NSArray. 사용해 보았다.
 
NSArray *pathComponents = [path pathComponents];
 
배열로 돌아왔으니 루프를 돌리면서 찍어보자.
아.. 루프 돌리는 법을 모르네... 문법 참조. (The Objective-C Programming Language - Fast Enumeration)
 
for (NSString *element in pathComponents){
    NSLog(element);
}
 
무난히 완성!!!
 


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

댓글을 달아 주세요

아이폰어플개발정보2010. 8. 30. 10:07
아이폰 어플 간단한 코딩 따라해보기

과제B. WhatATool (Part I) (원본)

Objective-C의 문법은 스탠다드 C의 문법 + 약간의 Objective-C고유의 문법이라고 할 수 있으며 Objective-C자체는 많은 유용한 함수들을 제공한다.

여기서는 Objective-C의 기본 클래스들을 이용하여 간단한 로그를 찍어봄으로써 "코딩 맛보기"를 해본다.

1.Xcode를 기동하여 신규 프로젝트 생성에서 Command Line Utility > Foundation Tool 을 선택한다.

  (프로젝트 명은 WhatATool 이라고 해보자)

2.생선된 프로젝트 파일 일람중에 WhatATool.m을 열어본다.

  여기엔 이미 기본적으로 아래와 같은 main 함수가 만들어져 있다.

#import

int main (int argc, const char * argv[]) {

    NSAutoreleasepool * pool = [[NSAutoreleasePool alloc] init];
    NSLog(@"Hello World");

    [pool release];
    return 0;
}

이 상태로 실행해본다. 메뉴의 Build > Build and go 클릭.

성공했다고 나오지만 화면엔 아무 변화가 없다. Hello World는 어디에 찍히는 걸까? 로그파일?

정답은, 콘솔에 나온다.

콘솔은 메뉴의 Window > Console 을 클릭하면 보인다.

이제 이 프로젝트에 4가지 소스를 추가해보자.

<순서>

1.사용자 홈 디렉토리 찍어보기 (NSString 클래스 이용)

2.프로세스 ID 찍어보기 (NSProcessInfo 클래스 이용)

3.즐겨찾기 만들어보기 (NSMutableDictionary 클래스 이용)

4.Selector 의 이용과 Class 정보 보기

이 4가지 섹션에선 모두 NSLog 클래스를 이용하여 정보를 콘솔에 출력한다.

NSLog는 기본적으로 유저 메세지 앞에 시간, 프로세스명, 프로세스ID 등을 붙여준다.

   예 : 2008-09-23 13:49:42.275 WhatATool[360] Your message here.



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

댓글을 달아 주세요

아이폰어플개발정보2010. 8. 19. 15:24
아이폰 어플의 기본원리를 파악하면 어플 개발이 쉬워..

한국에 iPhone 개발자가 더 쉽게 개발 할 수 있기를 기원하며 이 튜토리얼을 작성합니다.

먼저 이 튜토리얼의 대상자는 Objective-C 와 Cocoa를 이용하여 Mac 어플리케이션 개발 경험이 있는 사람을 대상으로 합니다.

이 튜토리얼은 iPhone 개발을 빠르게 시작하기 위해 만들어졌습니다. 기본 아키텍쳐나 구조에 대해서는 ADC의 공식 문서를 참고하시기 바랍니다.

저도 지식이 부족한 편이기 때문에 틀린 내용이 다수 있을수도 있습니다. 지적 해주시면 바로바로 시정하겠으니 많은 지적 부탁드립니다.

iPhone OS technology layers (출처 : ADC - iPhone Dev Center)

iPhone OS 는 위의 그림과 같은 시스템 구조를 갖고 있습니다. 그중 우리가 주로 접근하고 개발하게 될 레이어는 코코아 터치 입니다. 물론 추후 아래 레이어로 내려가면서 개발하게 될 경우도 생길 것 입니다.

iPhone 개발을 크게 보면 게임과 애플리케이션 개발 2가지로 보겠습니다. 게임 개발의 경우 개발방법에 있어서 상이한 차이가 있으므로 제외하고 우리는 애플리케이션 개발을 하려고 합니다.

필요한 개발 환경
  1. Mac 계열 PC
  2. Xcode 3.1.2
  3. iPhone SDK 2.2
  4. 최신 펌웨어 업데이트가 되어있는 iPhone 혹은 iPod Touch

위와 같은 개발 환경을 갖추고 개발을 시작하면 무리 없이 개발을 시작할 수 있을겁니다. Xcode나 iPhone SDK의 버전은현재 제 환경을 쓴것이지 저 버전을 강요하지는 않습니다. iPhone 이나 iPod Touch 와 같은 경우도 시뮬레이터로만개발을 하실 경우에는 필요로 하지 않습니다.

My First App
  1. Xcode 를 열고 New Project 를 열고,  iPhone OS 카테고리의 Application 중 View-Based Application 를 선택하여 프로젝트를 생성합니다.
  2. 실행하여 실행화면을 확인해봅니다. (메뉴의 Project -> Set Active SDK 를 시뮬레이터로 바꿔서 실행하시기 바랍니다.)
iPhone Application Life Cycle

iPhone 애플리케이션은 사용자가 터치를 통해 실행하여 Home 버튼을 눌러 종료되는 사이클을 갖고 있습니다. 그 사이클을 도식화 하여 코드와 비교해보면 아래와 같습니다.

Application life cycle (출처 : iPhone Application Programming Guide)

iPhone 애플리케이션의 엔트리 포인트인 main 함수를 살펴 보겠습니다.

  1. int main(int argc, char *argv[]) {   
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        int retVal = UIApplicationMain(argc, argv, nil, nil);
        [pool release];
        return retVal;
    }

int UIApplicationMain (int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);

UIApplicationMain 함수는 아래와 같은 역할을 합니다.

  • 애플리케이션 객체를 생성
  • 애플리케이션 딜리게이트를 설정
  • 이벤트 루프

첫번째, 두번째 인자는 main 함수의 인자를 넘겨주면 되고, 세번째 principalClassName 인자는 nil 로 넘겨주면UIApplication 으로 애플리케이션 객체를 생성합니다. 여기서 주목할 곳은 네번째 인자인 delegateClassName입니다. 이 인자는 애플리케이션을 생성하고 딜리게이션을 할 클래스의 이름을 문자열로 넘겨줍니다. 이 인자를 nil 로 넘겨줄경우 이 애플리케이션의 main nib 파일의 딜리게이션 클래스로 딜리게이션 되게 됩니다. 애플리케이션 생성이 완료되면애플리케이션은 딜리게이션 객체에게 applicationDidFinishLaunching 메시지를 보냅니다. 그리고 애플리케이션이종료되기 전에는 applicationWillTerminate 메시지를 보냅니다.

애플리케이션 delegate 클래스의 applicationDidFinishLaunching 메시지를 살펴 보겠습니다.

  1. (void)applicationDidFinishLaunching:(UIApplication *)application {
        [window addSubview:viewController.view];
        [window makeKeyAndVisible];
    }

첫째줄에서는 UIWindow 객체에 UIView 객체를 subView 로 추가시켜주는 메시지를 보내고 있습니다. (UIWindow 와 UIView 는 다음 튜토리얼에서 자세히 다루겠습니다.)

둘째줄에서는 UIWindow 를 invisible 상태에서 visible 상태로 바꿔주는 메시지를 보내고 있습니다. 이것은인터페이스 빌더의 Window Attributes 탭의 View 속성 들중 Hidden 과는 조금 틀립니다. 아래 스크린샷의Visible at Launch 를 체크해주게 되면 makeKeyAndVisible 메시지를 보내지 않아도 애플리케이션 실행시에화면이 보여지게 됩니다.

여기까지 기본적인 iPhone 애플리케이션을 작성하는 법, 그리고 그 구조에 대해 배워봤습니다.

다음 튜토리얼에서는 이것들을 이용하여 UIWindow 와 UIView 그리고 UIViewController 들을 작성하여, 원하는 화면을 구성하고 이벤트를 처리해보도록 하겠습니다.

원본은 http://jweb.springnote.com/pages/2354454.xhtml 에서 작성되었고, 향후 수정시에 원본은 가장 최신 상태로 업데이트 됩니다.



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

댓글을 달아 주세요

아이폰어플개발정보2010. 8. 19. 15:23
아이폰 어플 개발할때 자주쓰는 자료 총 정리해 봅니다

원문 : http://improgrammer.com/12

KT앱 대회 준비하면서 모은 자료들을 정리해서 올립니다.
거의 맥부기 카페 자료들이 대부분인데 한곳에 모아서 찾아보기 쉬우라고 올려봅니다.


-푸쉬  서버  개발  관련 자료-
이지 APNS 오픈 소스 라이브러리
http://www.easyapns.com/
구글 코드 APNS 오픈 소스
http://code.google.com/p/apns-php/
서버 튜토리얼
http://blog.boxedice.com/2009/07/10/how-to-build-an-apple-push-notification-provider-server-tutorial/


-label이나 textView에 현재 시간을 표시하고 싶습니다-
NSDate *t = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSString *timeStr = [formatter setDateFormat:@"HH:mm:ss"];
myLabel.text = timeStr;
...
[textView scrollRangeToVisible:NSMakeRange([textView.text length]-1, 1)];


-시뮬레이터 포토 라이브러리 자신의 이미지 추가 방법-
UIImage * sShot = [UIImage imageNamed:@"imageName.jpg"];
UIImageWriteToSavedPhotosAlbum(sShot, nil, nil, nil);


-네이게이션바 스타일 바꾸기-
http://cafe.naver.com/mcbugi/1241


-이미지 자르기 함수를 소개합니다. (UIImage)-

- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/


-HTTP 라이브러리-
http://allseeing-i.com/ASIHTTPRequest/How-to-use


-json 관련-
라이브러리 http://code.google.com/p/json-framework/
json 투토리얼 http://iphonedevelopertips.com/networking/iphone-json-flickr-tutorial-part-1.html


-알럿 템플렛-
self.myAlertView = [ [UIAlertViewalloc]
initWithTitle:@"알림"
message:@"이메일을입력해주세요"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"확인", nil];
self.myAlertView.delegate = self;
[self.myAlertViewshow];


-푸쉬서버 구현을 위한 서버 인증서 pem 만들기-
애플 개발자 센터 apps ID 추가 (이때 와일드카드(*)는 사용하면 안됨)

키체인에서 개인 인증서 하나 만들어 애플 개발 센터에 등록

애플 개발센터에서 cert파일을 다운받아서 키체인으로 추가

키체인에서 내보내기로 p12파일로 저장

커맨드에서  p12파일을 pem파일로 변환
openssl pkcs12 -in quizers_dev_cert.p12 -out quizers_dev_cert.pem -nodes -clcerts


-전역변수를 사용해 보자...-
http://cafe.naver.com/mcbugi/55643


-JSON 2중 뎁스 이상 키 접근하기-
NSDictionary*feed =[self downloadPublicJaikuFeed];
// get the array of "stream" from the feed and cast to NSArrayNSArray*streams =(NSArray*)[feed valueForKey:@"stream"];
// loop over all the stream objects and print their titlesint ndx;
NSDictionary*stream;
for(ndx =0; ndx < stream.count; ndx++){
        NSDictionary*stream =(NSDictionary*)[streams objectAtIndex:ndx];
        NSLog(@"This is the title of a stream: %@", [stream valueForKey:@"title"]); 
}


-배열 NSArray-
초기 데이터로 생성
NSArray *array = [[NSArray alloc] initWithobjects:추가할 객체들.. , nil];
 스트링으로 생성
NSArray *joins =(NSArray*)[result objectForKey:@"joins"];
길이 구하기
NSLog(@"Array size : %d " , sizeof(BUILDING_DATA) / sizeof(BUILDING_DATA[0]));


-NSString 클래스를 이용하여 문자을 넣자니 유니코드를 받아 초기화-
-(NSUInteger) UnicharLength:(const unichar*)str
{
unichar* pStr = (unichar*)str;
for( ; pStr[0] != nil ; pStr++ );
return (NSUInteger)(pStr - str);
}
[[NSString alloc] initWithCharacters:(원본문자열) length:[self UnicharLength:(원본문자열)]];


-랜덤 출력-
srandom(time(NULL));
value = random() % 100;
위처럼 하시면 0~99사이의 한수를 리턴합니다.
srandom(time(NULL)); 는 첨에 한번만 해주시면 됩니다.


-Code Sign error: Provisioning profile이 맞지 않을 때 변경 방법-
여러 장비에서 작업을 하거나 여러 프로젝트를 진행 중에 변경된 Provisioning profile이 적용되지 않아 Debug를 할 때 ”Code Sign error: Provisioning profile ‘3E6AA725-6534-46F8-B9CE-D19AC9FD854B’ can’t be found” 이런 오류가 발생하는 경우가 있는데요. 이럴 때 현재 사용중인 Provisioning Profiles로 프로젝트 세팅을 변경해주는 방법을 소개한 글(원문)이 있어서 공유합니다.

1. 실행중인 Xcode Project를 닫습니다.
2. Finder에서 프로젝트 폴더로 이동합니다.
3. 프로젝트 .xcodeproj 파일 선택하고 마우스 오르쪽 키를 눌러 '패키지 내용 보기'를 선택합니다.
4. 패키지 내용 보기를 통해 패키지 안에 있는 project.pbxproj 파일을 Xcode로 불러옵니다.
5. 검색을 통해 PROVISIONING_PROFILE 부분을 찾아 변경된 Provisioning profile 로 변경해줍니다.
6. 현재 Provisioning profile을 확인하려면 Organizer 창을 열어보면 알 수 있습니다.
7. Window > Organizer로 Organizer 창을 열고 왼쪽에 IPHONE DEVELOPMENT > Provisioning Profiles로 이동합니다.
8. 오른쪽에 있는 Profile Identifier를 복사해서 변경해주면됩니다.
9. 변경이 끝나면 project.pbxproj 저장하고 프로젝트를 열어 테스트합니다.


-아이폰 웹개발에서 디바이스 아이디 가져올수있나요?-
[[UIDevice currentDevice] uniqueIdentifier];



-Accessing Objects in a NSArray-
To access an object in an NSArray, you use the -objectAtIndex: method, as in the following example:NSArray *numbers;
NSString *string;

numbers = [NSArray arrayWithObjects: @"One", @"Two", @"Three", 
                                     nil];
string = [numbers objectAtIndex: 2];   // @"Three"

Of course, you have to be careful not to ask for an object at an index which is negative or bigger than the size of the array; if you do, an NSRangeException is raised (we'll learn more about exceptions in another tutorial).
To get the length of an array, you use the method -count, as in:
NSArray *numbers;
int i;

numbers = [NSArray arrayWithObjects: @"One", @"Two", @"Three", 
                                     nil];
i = [numbers count];   // 3


-상태바 제어-
안 보이게
[UIApplication sharedApplication].statusBarHidden = NO;

스타일
UIApplication *myApp = [UIApplication sharedApplication];
[myApp setStatusBarStyle:UIStatusBarStyleBlackOpaque];


-메모리 오버되어서 어플이 죽는 경우에 호출되는 이벤트??-

뷰컨트롤러 베이스로 작업을 한다면

- (void)didReceiveMemoryWarning

함수로 메모리가 위험할시에 위 함수를 핸들링하니 내부에 관련 대응할 처리를 구현해주면 됩니다.



-D-Day 구하기-
NSDate* date  = [NSDatedateWithNaturalLanguageString:@"2010-06-30"];
NSDate* d_day = [NSDatedateWithNaturalLanguageString:@"2010-12-31"];

NSDateComponents *dcom = [[NSCalendar currentCalendar]components: NSDayCalendarUnit
fromDate:date  
  toDate:d_day  
  options:0];

NSLog(@"day=%d",   [dcom day]);   // 184


-라디오 버튼이나 체크박스등을 찾지를 못하고  있는데-
Interface Builder 에서 library를 보시면 segmented control, switch가 보일겁니다.
말씀하시는 라디오버튼이나 체크박스는 없지만  
라디오버튼은 segmented control로 대체, 체크박스는 switch 로 대체하셔서 사용하시면 될듯합니다.


-책장 넘기기 효과-
UIView 를 하나 만들고 그 안에 UIImageView 를 만들었습니다.
이제 이미지뷰어의 내용을 채울때 책장을 넘기듯이 넘기는 방법입니다.

[UIView baginAnimations:@"stalker" context:nil]; <- stalker 는 UIView 의 이름입니다
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:stalker cache:YES];
[UIView setAnimationDuration:1.0];
imageView.image = [UIImage imageNAmed:이미지파일명];
[UIView commitAnimations];

이 걸 터치 이벤트나 이런곳에 삽입하면
책장을 넘기듯이 이미지의 전환이 일어납니다. 


-image를 fade out 효과-
[UIView beginAnimations:nil context:NULL];
[imageView setAlpha:0.0];
[UIView commitAnimations]; 


-UIView Animation 중복방지-
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
....
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
        [UIView commitAnimations];

이런 식으로 에니메이션을 만들었는데 간단하게 UIImageView를 한점에서 다른 한점으로 이동시킵니다.
근데 그래서 에니매이션이 끝나면 다시 또다른 다른 두 좌표로 해서 위의 코드가 실행되서 계속해서 UIImageView를 움직이게 하고 있습니다.

근데 질문은 1. setAnimationDidStopSelector 에서 에니매이션이 끝난것을 알기전에 강제로 에니메이션을 멈출수 있나요?
2. 제 경우에는 어떤 경우에 위 코드가 setAnimationDidStopSelector 가 호출되었을때 만 실행되는 것이 아니라 다른 부분에서도 호출하기도 합니다.  근데 문제는 동시에 위 코드가 중복되어서 호출되면 이상하게 작동해요.  그래서 꼭 위 코드를 실행(에니매이션을 commit 하기전에는 반드시 에니메이션을 강제로 멈추던지 아니면 다른 체크를 해야 할것 같은데.....  

혹시 방법이 있으면 부탁드립니다.

꾸벅~

답글 : 
[UIView setAnimationsEnabled:NO];
// 에니메이션을 종료 합니다. 


-일정시간 딜레이 후 함수 호출-
[self performSelector:@selector(playerStop) withObject:nil afterDelay :1.0f];

-(void) playerStop 
{
}


-개발 완료, 베타 테스팅용 Ad Hoc 배포-
http://cafe.naver.com/mcbugi/9042


-테이블뷰에 원격이미지를 넣을경우 스크롤이 느려지는 현상-
LazyTableImages 샘플http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009394
AsyncImageView 클래스 http://www.markj.net/iphone-asynchronous-table-image/


-테이블 뷰 섹션별로 이름 주기-
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if( section == 0 ) {
return@"발행한퀴즈";
} elseif( section == 1 ) {
return@"참여한퀴즈";
} else {
return@"진행중인퀴즈";
}
}


-정사각형으로 사진을 CROP 하고, 썸네일 크기에 맞게 리사이즈-
먼저, 출처는 다음 기사입니다.
http://tharindufit.wordpress.com/2010/04/19/how-to-create-iphone-photos-like-thumbs-in-an-iphone-app/ 

iPhone 사진앨범의 특징은 가로나 세로가 긴 이미지라 할지라도,
정사각형으로 사진을 CROP 하고, 썸네일 크기에 맞게 리사이즈 시킵니다.

위의 기사의 내용을 나름대로 보기 편하게(?) 수정을 했습니다.

함수명 - makeThumbnailImage
파라미터 - 원본 이미지, 리사이즈없이 CROP만 할지 여부, 리사이즈할 정사각형 한변의 길이
리턴값 - CROP 및 리사이즈된 이미지

- (UIImage*) makeThumbnailImage:(UIImage*)image onlyCrop:(BOOL)bOnlyCrop Size:(float)size
{
 CGRect rcCrop;
 if (image.size.width == image.size.height)
 {
  rcCrop = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
 }
 else if (image.size.width > image.size.height)
 {
  int xGap = (image.size.width - image.size.height)/2;
  rcCrop = CGRectMake(xGap, 0.0, image.size.height, image.size.height);
 }
 else
 {
  int yGap = (image.size.height - image.size.width)/2;
  rcCrop = CGRectMake(0.0, yGap, image.size.width, image.size.width);
 }

 CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rcCrop);
 UIImage* cropImage = [UIImage imageWithCGImage:imageRef];
 CGImageRelease(imageRef);
 if (bOnlyCrop) return cropImage;

 NSData* dataCrop = UIImagePNGRepresentation(cropImage);
 UIImage* imgResize = [[UIImage alloc] initWithData:dataCrop];

 UIGraphicsBeginImageContext(CGSizeMake(size,size));
 [imgResize drawInRect:CGRectMake(0.0f, 0.0f, size, size)];
 UIImage* imgThumb = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 [imgResize release];
 return imgThumb;
}

위 소스를 참고하시면, 이미지를 CROP 하는 방법이나, 이미지를 RESIZE 하는 방법을 참고하실수 있을겁니다.

사족을 붙이자면, 왜 Resize 할지 여부를 따로 분리 시킨 이유는 실제로 사용을 해보면 Resize 루틴에서
많은 CPU 부하가 걸립니다. 그래서 UIImageView 에  contentMode를 UIViewContentModeScaleAspectFit 로 설정해서
자체적으로 리사이즈를 하게 하는 방법이 비동기적으로 괜찮습니다. (물론.. 실제 Resize된 이미지가 아니므로 메모리적인 소비는 있습니다.)

많은 도움 되셨으면 좋겠네요 ^^


-사진찍을때  아래에서  올라오는  메뉴 UIActionSheet-
http://ykyuen.wordpress.com/2010/04/14/iphone-uiactionsheet-example/


-uibutton disable-
http://www.iphonedevsdk.com/forum/iphone-sdk-development/2499-uibutton-disable.html


-이미지  슬라이드  샘플-
http://lievendekeyser.net/index.php?module=messagebox&action=message&msg_id=1351


-커버플로우  라이브러리-
http://apparentlogic.com/openflow/


-Xcode3.2.3과 SDK4로 업그레이드 후, 기존 앱 업그레이드 하는 법-
XCode3.2.3 과 SDK4로 버전업한 후, 기존 앱을 업그레이드 할 때 간단한 Tip 입니다.
1. XCode3.2.3과 SDK4로 업그레이드 한다. 별도로 기존 XCode 3.1 버전을 따로 보관할 필요가 없습니다.
2. 기존 앱을 새 XCode3.2.3에서 연다.
3.Group & Files를 right click -> Get Info 후
  3-1.General Tab 에서
Project Format 을 Xcode 3.2-compatible 로 바꾼다.
 3-2.Build Tab 에서
 Base SDK를 iPhone Device 4.0(배포시), 혹은 iPhone Simulator 4.0(테스트시) 로 바꾼다
 iPhone OS Deployment Target 을 iPhone OS 3.0 (즉 지원하고자 하는 하위버전으로) 로 바꾼다.
이렇게 하시면 됩니다.


-객체 타입 비교-
if ( [a isKindOfClass:b] )


-문자열 비교-
NSString *strText = idField.text;
if([srText isEqualToString:@"mihr01"])
....
else if([srText isEqualToString:@"mihr02"])
....
else
...
이렇게 하셔도 되고요 완전 같은 스트링이 아니라

포함된것을 찾으려면
if([strText rangeOfString:@"mihr01"].length) 


-탭뷰에 스타일시트를 붙일때-
UIActionSheet *popupQuery = [[UIActionSheetalloc]
initWithTitle:nildelegate:self
cancelButtonTitle:@"취소"
destructiveButtonTitle:nil
otherButtonTitles:@"사진찍기", @"기존의사진선택", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
QuizersAppDelegate *appDelegate = (QuizersAppDelegate *)[[UIApplicationsharedApplication] delegate];
[popupQuery showInView:appDelegate.window];


-스크롤  밀어서  데이터  리플래쉬  하기-
소스코드
http://github.com/facebook/three20/tree/master/samples/TTTwitter/
설명
http://www.drobnik.com/touch/2009/12/how-to-make-a-pull-to-reload-tableview-just-like-tweetie-2/


-테이블뷰 위에 검색창 붙이는 방법-
테이블뷰 위에 검색창 넣으신 후에, viewDidLoad 메서드 부분에 [table setContentOffset:CGPointMake(0.0, 44.0) animated:NO];해주시면 처음 보여질 때는 검색창이 안 보이다가 밑으로 땡기면 나타나게 됩니다.


-네트워크  연결  됐는지  확인 Reachability-
http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/
http://theeye.pe.kr/entry/how-to-check-network-connection-on-iphone-sdk



-아이폰 강제종료 버튼 이벤트-
아래 메소드가 어플이 종료될 때 수행되는 함수입니다.
종료될 때에 각종 리소스들을 Free시킬 경우에 사용됩니다.
참고하시면 될 듯 합니다~
 - (void)applicationWillTerminate:(UIApplication  *)application



-크랙 방지 클래스-
http://cafe.naver.com/mcbugi/11661



-어플을 강제 종료하는 API 는 아이폰에서 제공하지 않는다?-
http://cafe.naver.com/mcbugi/11803



-탭바 클릭시 바로 UISearchBar 클릭되도록 할려면 어떻게 해야 하나요?-
UISearchBar가 first responder가 되게 하면 됩니다.

[searchBarObj becomeFirstResponder];




-UITextField 입력값 체크하기 : 문자열 길이, 숫자여부 체크-

헤더(.h)에 UITextFieldDelegate 선언

@interface 클 래스명 : UIViewController

구현부(.m)에 다음 메쏘드를 구현하면 됨

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 

//return NO하면 입력이 취소됨
//return YES하면 입력이 허락됨
//textField 이용해서 어느 텍스트필드인지 구분 가능

//최대길이

int maxLength = 128;

NSString *candidateString;

NSNumber *candidateNumber;

//입력 들어온 값을 담아둔다

candidateString = [textField.text stringByReplacingCharactersInRange:rangewithString:string];


if(textField == IDField) {
maxLength = 8;
} else if(textField == AgeField) {
//숫자여부 점검

//length가 0보다 클 경우만 체크
//0인 경우는 백스페이스의 경우이므로 체크하지 않아야 한다

if ([string length] > 0) {

//numberFormatter는 자주 사용할 예정이므로 아래 코드를 이용해서 생성해둬야함

//numberFormatter = [[NSNumberFormatterallocinit];

//[numberFormattersetNumberStyle:NSNumberFormatterDecimalStyle];


//numberFormatter 를 이용해서 NSNumber로 변환

candidateNumber = [numberFormatter numberFromString:candidateString];

//nil이면 숫자가 아니므로 NO 리턴해서 입력취소

if(candidateNumber == nil) {

returnNO;

}

//원 래 문자열과 숫자로 변환한 후의 값이 문자열 비교시 다르면

//숫자가 아닌 부분이 섞여있다는 의미임

if ([[candidateNumber stringValuecompare:candidateString] != NSOrderedSame) {

return NO;

}

maxLength = 2;

}

}

//길이 초과 점검

if ([candidateString length] > maxLength) {

returnNO;

}

return YES;

}

http://cafe.naver.com/mcbugi/37651



-How to split string into substrings on iPhone?-
http://stackoverflow.com/questions/594076/how-to-split-string-into-substrings-on-iphone



-메모리 누수-
http://cafe.naver.com/mcbugi/64257


-디바이스 가로 세로 상태-
UIDeviceOrientationIsLandscape([UIDevicecurrentDevice].orientation) ?


-UITextField 에 자동 포커스 주기-
키보드 올리면서 커서를 넣을때는 아래방법을 이용하시면 됩니다.
[textField becomeFirstResponder]; 
참고로 이건 커서를 빼면서 키보드를 내리실때 사용하시면 되구요...
[textField resignFirstResponder]; 


-홈버튼이 눌렸을 때도 텍스트뷰 내용을 저장하려면 어떻게 해야할까요?-
- (void)applicationWillTerminate:(UIApplication *)application / Application Delegate 메서드 부분에 구현하시면 되지않을가요? 


-3.2 4.0  동영상  플레이-
http://iphonedevelopertips.com/video/getting-mpmovieplayercontroller-to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html


-한글완성형(EUC-KR)을 iPhone/Mac에서 사용할 수 있는 언어셋으로 변환하기-
http://blog.backpackholic.tv/160


-인터페이스 함수들을 편하게 가져오는 방법-
http://code.google.com/p/xcode-auto-assistant/


-#pragma mark로 코드 쉽게 구분하기-
http://cafe.naver.com/mcbugi/64408


-os4에서 applicationWillTerminate가 안먹어서 알게된것-
os4에서 applicationWillTerminate: 가 안먹어서 삽질하다가 알아낸 결과입니다.
뒷북 인지는 모르지만 혹시 모르시는 분을 위해서 적어봅니다.
os3.x 에서는 홈버튼을 한번만 누르면 applicationWillTerminate 가 아주 잘 호출됩니다.
하지만 os4 에서는 홈버튼을 한번만 누르면 
applicationDidEnterBackground 가 호출됩니다.
os4 에서 멀티태스킹을 위해서 좀 바뀌었습니다.
os4에서도 홈버튼 한번 누를때 applicationWillTerminate 가 호출되게 하려면
info.plist 에서 'Application does not run in background' 이 속성을 추가해주면 됩니다.
위 속성이 없으면 기본적으로 멀티태스킹이 되는걸로 간주합니다. (진짜 멀티태스킹은 아니지만)
위 속성이 없을때 호출되는 메소드를 실험해 봤습니다.
-----------------------------------------------------------------
처음 어플을 실행시키면
     didFinishLaunchingWithOptions, 
applicationDidBecomeActive 
이 호출되고
홈버 튼을 한번 만 누르면
applicationWillResignActive, 
applicationDidEnterBackground
호출되면서 어플이 종료되고
이상태에서 다시 어플을 실행시키면
applicationWillEnterForeground, 
applicationDidBecomeActive 
호출됩니다.
홈버튼을 두번 누르면
applicationWillResignActive
이 호출됩니다.
----------------------------------------------------------------
'Application does not run in background' 을 체크하면
홈버 튼을 한번만 누르면 applicationWillTerminate 를 호출합니다.
'근데 속성 체크 안했을때 applicationWillTerminate 는 호출이 안되는건지 궁금하네요.
아시는 분 좀 알려주세요.

답글 : 
Applicationwillterminate함수 대신에 applicationDidENterBAckground 사용하라고하네여 이곳에서 공유자원해제나 사용자데이타 저장,타이머 무효화,어플상태정보등 저장을 하라고 합니다. http://cafe.naver.com/mcbugi/65497


-COCOS2D 번개 효과-
http://www.cocos2d-iphone.org/forum/topic/370


-iPhone 4.0 호환 키보드에 버튼 or 뷰 붙이기-
기존꺼에 비해 약간 수정되 었을뿐입니다....
하지만 -_-이거 찾느라 ㅠㅠ;; 

3.1.x에서는 windows 서브뷰에 항상 키보드 뷰가 있었지만 ...
4.0 부터는 windows 에 항상 있는게 아니고, 키보드를 불렀을때 -_- 붙어서 오더라고요.. 그래서

Done 버튼 붙이는 예제 입니다. (Number 패드에)

아래 액션을 Text필드의 BeginTouched 에 연결 시킵니다.
 // 키보드가 나왔을때랑 사라질때의 이벤트를 잡아냅니다.
//3.1.X 에서는 UIKeyboardWillShowNotification 으로 잡지만
// 4.0 때문에 --; DidShow로 잡아줬습니다.
//그래야 윈도우에 키보드가 있더라고요 ;;;
-(IBAction)FieldTouched{

    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillShow:) 
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillHide:) 
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];


}

// 키보드가 나왔을때 Done 버튼 붙여주기 
- (void)keyboardWillShow:(NSNotification *)note {  

    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
    doneButton.frame = CGRectMake(0, 163, 106, 53);
    doneButton.adjustsImageWhenHighlighted = NO;
    [doneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
    [doneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
    [doneButton addTarget:self action:@selector(backgroundTap:) forControlEvents:UIControlEventTouchUpInside];

    //3.1.x 와 4.0 호환 키보드 붙이기
    for( UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows] ){
        for( UIView *keyboard in [keyboardWindow subviews] ){
            NSString *desc = [keyboard description];
            if( [desc hasPrefix:@"
               [desc hasPrefix:@"
               [desc hasPrefix:@"
            {
                [keyboard addSubview:doneButton];
            }
        }
    }

}

// 키보드가 없어질때 Done 버튼을 삭제 합니다.
- (void)keyboardWillHide:(NSNotification *)note {  

    for( UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows] ){
        for( UIView *keyboard in [keyboardWindow subviews] ){
            NSString *desc = [keyboard description];
            if( [desc hasPrefix:@"
               [desc hasPrefix:@"
               [desc hasPrefix:@"
            {
                for(UIView *subview in [keyboard subviews])
                {
                    [subview removeFromSuperview];
                }

            }
        }
    }
}

도 움 되시길 바랍니다 ;)
http://cafe.naver.com/mcbugi/62349


-배열내 숫자 값 비교해서 정렬하기-

만약에 객체내의 인스턴스를 키로 정렬할 경우에는 NSSortDescriptor 를
쓰시면 됩니다.
아래는 name으로 정렬한 예입니다.
@interface Test :
NSObject {
NSString *name;
double distance;
}
@property
(nonatomic, retain) NSString *name;
@property double
distance;
@end
@implementation Test
@synthesize name, distance;
@end
아 래는 사용방법입니다.
       Test *t1 = [[Test alloc] init];
Test *t2 = [[Test alloc] init];
Test *t3 = [[Test alloc] init];
[t1 setName:@"마바사"];
[t2 setName:@"아자차"];
[t3 setName:@"가나다"];
[t1 setDistance:1.2];
[t2 setDistance:2.5];
[t3 setDistance:0.5];
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:t1];
[array addObject:t2];
[array addObject:t3];
[t1 release];
[t2 release];
[t3 release];
// 이름순으로 정렬
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCompare:)];
[array sortUsingDescriptors:[NSArray arrayWithObjects:nameSort, nil]];
[nameSort release];
for(Test *t in array) {
NSLog(@"%@ %f", [t name], [t distance]);
}
[array removeAllObjects];
------[결 과]------
2010-07-12 17:46:13.117 Sort[5070:20b] 가나다 0.500000
2010-07-12 17:46:13.125 Sort[5070:20b] 마바사 1.200000
2010-07-12 17:46:13.130 Sort[5070:20b] 아자차 2.500000
p.s. distance로 정렬하고자 한다면 
NSSortDescriptor *distanceSort = [[NSSortDescriptor alloc] initWithKey:@"distance" ascending:YES];
nameSort 대신 distanceSort를 넣으시면 됩니다.

http://cafe.naver.com/mcbugi/65873


-[TIP] 시뮬레이터 사진앨범에 사진넣기-
1) 시뮬레이터를 실행시킵니다.

2) 맥에서 포토라이브러리에 넣을 사진을 시뮬레이터로 Drag&Drop 합니다.

3) 그러면, 사파리가 열리면서 Drag한 이미지가 표시가 될겁니다.

4) 그 표시된 이미지를 마우스로 꾸~~~~~~욱 눌러줍니다.

5) 그러면, 메뉴가 뜨면서 이미지를 저장할건지 복사할건지를 묻습니다.

6) 이미지 저장을 누릅니다.

7) 이제 시뮬레이터의 사진앨범에 가 보시면 아까 저장한 사진이 들어가있을겁니다.



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

댓글을 달아 주세요