과정
=====
1. 오거나이저의 repositories에서 추가(+)버튼을 누르고 Checkout 이나 Clone Repository를 고른다.
2. 파일의 패스나 URL을 입력한다.
3. "Host is reachable" 인디케이터가 녹색으로 바뀌면 Next버튼을 클릭한다.
4. Repository용 로컬 이름을 입력하고 Clone이나 Checkout으로 그것을 복사한다.
5. 위치를 고르고 선택된 Clone(또는 Checkout) 버튼을 클릭해 로컬 repository를 저장한다.


-----------------------------------------

로컬 시스템에 사본을 만들기 위해 Check out이나 clone을 수행한다.

일반적인 repository 작업의 추상화로  Xcode는 Git과 Subversion(SVN) 모두 싱글 또는 통합 GUI 및 작업수행과정의 저장소를 제공한다. 무엇을 선택하느냐에 따라 이 작업은 저장소를 check out(SVN용)하거나 clone(Git용)하며 프로젝트에 적용한다.

Xcode에서 Git 저장소를 클로닝하는 것은 로컬 시스템에 저장소를 세팅하고, 작업 공간에서 바로 쓸 수 있는 저장소로 만들어준다. 이 방법은 온라인이거나 오프라인이거나 상관없이 배포 버전 관리 및 코드 백업의 모든 권한을 관리할 수 있는 장점이 있다.

SVN 체크아웃 작업은 로컬 저장소를 만들지 않는다. 따라서 반드시 변화된 결과물을 저장할 수 있는 저장소 서버를 준비해야 한다.

SVN용으로 반드시 trunk, branches, tags 디렉토리로의 상대주소도 준비해야한다. 이렇게 하면, 저장소 오거나이저에서 새로운 저장소의 이름을 클릭해 간단히 필드를 채울 수 있다. 만약 SVN 서버가 인증을 필요로 한다면 유저명과 비번도 채워넣어야 한다.

이 비디오는 Sketch 샘플 코드 프로젝트가 Git 저장소를 클로닝 하는 과정을 보여준다.

Creative Commons License
2011/05/11 04:21 2011/05/11 04:21
과정
====
1. 진행할 프로젝트의 임시 사본을 보관하도록 mkdir 커맨드를 이용해서 branches, tags, trunk 이렇게 3개의 서브디렉토리를 생성한다.

2. trunk 서브 디렉토리에 진행할 Xcode 프로젝트를 복사해 넣는다.

3. 빈 Subversion repository를 만들기 위해 svnadmin create 명령을 사용한다.

4. 새로운 Subversion repository에 진행할 프로젝트를 임포트하기 위해서 svn import 명령을 사용한다.



-------------------------------------------------------------
Subversion repository를 설치하기 위해 커맨드라인 명령을 사용한다.

Subversion repository를 설치하려면, Shell을 이용해야만한다. 기본 제공하는 bash쉘인 Terminal을 이용한다.
(/Applications/Utilities/Terminal.app에 있다)

만약 진행중인 프로젝트가 없다면 Xcode를 이용해서 repository를 설치하기 전에 새로운 프로젝트를 생성한다.

스텝 1.
프로젝트의 사본을 임시로 보관할 디렉토리 구조를 생성한다. 예를 들어 Sketch_svn_tmp라는 디렉토리를 다음 명령을 이용해 생성해 본다.
  • mkdir /Repo_Master/Sketch_svn_tmp

mkdir 커맨드는 지정된 패스의 가장 마지막 패스만을 생성한다. 따라서 위의 예에서 /Repo_Master라는 디렉토리는 이미 존재해야한다.

==Tip== 현재 위치의 폴더를 터미널로 집어 던지면 풀 패스가 표시된다.

관례적으로 SVN repository 는 3개의 서브 디렉토리를 포함하며 그 이름은 다음과 같다. branches, tags, trunk.
다음 명령어는 이 세 서브 디렉토리를 Sketch_svn_tmp 디렉토리에 생성해줄 것이다.
  • mkdir /Repo_Master/Sketch_svn_tmp/trunk
  • mkdir /Repo_Master/Sketch_svn_tmp/branches
  • mkdir /Repo_Master/Sketch_svn_tmp/tags


스텝2.
임시 구조의 셋업이 끝났으면 이제 진행할 프로젝트를 trunk 서브 디렉토리에 넣는다. 예를 들자면 다음 커맨드를 이용해 /Developer/Examples 폴더에 있는 Sketch 프로젝트 폴더와 그 내용물을 복사해 넣을 것이다.
  • cp -R /Developer/Examples/Sketch /Repo_Master/Sketch_svn_tmp/trunk


스텝3.
빈 Subversion repository를 생성한다. 예를 들자면 /Repo_Master 폴더에 위치하는 Sketch_svn이라는 이름의 repository 를 원한다면 다음의 svnadmin 명령을 이용하면 된다.

svnadmin create /Repo_Master/Sketch_svn



위애서 설명한 대로 /Rempo_Master는 생성된 상태에서 해야 /Sketch_svn이 생성된다.

스텝4.
이제 임시 구조에서 새로운 repository로 import해서 Subversion 소스 관리 상태로 둔다. 다음 명령으로 수행할 수 있다.
  • svn import /Users/myUserName/Projects/Sketch_tmp \
  • file:///Users/myUserName/Repositories/Sketch_svn -m "Initial import"



주의 :
*위 첫번째 줄의 백슬래시(\)는 다음 줄과 이어진다는 의미다. 한 줄로 쓸 땐 생략할 수 있다. 백슬래시를 쓴다면 그 뒤에는 빈칸이 없는 상태에서 RETURN키를 누른다.
*다음 문자열의 /는 3개가 맞다. file:///
*한 줄로 입력할 때에는 file:/// 앞에 빈칸을 하나 넣는다.
*따옴표(")를 이용하면 커멘트를 넣을 수 있다. 그러나 누구나 알아볼 수 있는 문장을 쓰도록 한다.


만약 import명령이 제대로 끝나면 다음 그림처럼 임포트 된 프로젝트 파일들이 배열될 것이다.


사용자 삽입 이미지


그림은 Sketch_svn Subversion reository를 만들고 Sketch 프로젝트를 그 안에 넣은 걸 보여준다. 제대로 되었다면 그림처럼 보일 것이다.






















Creative Commons License
2011/05/11 04:06 2011/05/11 04:06

트랜지션

from 학습/iOS 2011/04/07 22:57
(1)트랜지션 애니메이션 설정
================
트랜지션 애니메이션을 하려면 UIView애니메이션 설정 개시 시 UIView클래스의 setAnimationTransition:forView:cashe:메소드를 부른다


(중략)

트랜지션 애니메이션의 종류는 다음과 같다. 단, 캐쉬를 NO로 하면 트랜지션 애니메이션 중에도 뷰의 화상이 갱신 되도록 된다.

(중략)

(2) 뷰의 갱신
========
UIView클래스의 setAnimationTransition:forView:cashe:메소드와 commitAnimation메소드의 사이에 뷰를 갱신한다. removeFromSuperview메소드로 현재 뷰를 새로운 뷰로부터 해제하고 addSubview:메소드로 서브뷰를 추가한다.


(중략)


뷰의 생성자체는 beginAnimation:context:메소드보다 먼저 한다. 그렇지 않으면 애니메이션 완료까지 다음 뷰가 표시되지 않는다.
Creative Commons License
2011/04/07 22:57 2011/04/07 22:57

LayerAnimation

from 학습/iOS 2011/04/07 17:44
(1)레이어 생성
========
레이어를 생성하려면 CALayer클래스의 layer메소드를 사용한다.

(중략)

주요 프로퍼티는 다음과 같다.

(중략)

또, UIImage오브젝트로부터 CGImageRef형의 이미지를 취득하려면 CGImage프로퍼티를 사용한다.

(중략)

(2) 뷰에 레이어 추가
============
뷰에 레이어 추가하려면 UIView클래스의 layer프로퍼티에서 뷰의 레이어를 취득해 addSublayer: 메소드로 레이어의 서브 레이어로 추가한다.

(중략)

(3) 레이어 애니메이션 생성
===============
레이어 애니메이션을 생성하려면 CABasicAnimation클래스의 animationWithKeyPath: 메소드를 사용한다.

(중략)

이번에는 3차원의 어파인 변환을 하는 transform 프로퍼티를 변경대상으로 하며 keyPath에는 "transform"을 지정한다. 주요 프로퍼티는 다음과 같다.

(중략)

CAAnimation 클래스의 CALayer클래스는 CAMediaTiming 프로토콜을 구현하고 있다.
애니메이션 개시시와 종료시의 값에는 프로퍼티에 지정하는 값을 대입한다. 형은 id 형으로 조작하는 프로퍼티가 CGPoint나 CGRect나 CATransform3d등의 구조체일때는 NSValue클래스 메소드를 사용해 오브젝트 형을 변환하면서 대입한다.

(중략)

이 프로그램에서는 transform프로퍼티에 대해 회전 없이 (CATransform3DIdentity)로부터 Y축으로 180도 회전((CATransform3DMakeRotation(M_PI,0,1,0))하도록 설정했다.


(4) 3차원 어파인 변환
============
3차원 어파인변환으로 이용하는 주요함수는 다음과 같다.

(중략)

또, 상수 CATransform3DIdentity는 동일 행렬이다. 평행이동, 회전, 확대 축소등의 변환을 하지 않는 행렬이 된다.

(5)레이어의 레이어 애니메이션 추가
====================
레이어로 레이어 애니메이션을 추가하려면 CALayer 클래스의 메소드를 사용한다.

(중략)

키를 이용해 레이어로부터 애니메이션을 취득할 수 있다.

(후략)

Creative Commons License
2011/04/07 17:44 2011/04/07 17:44

UIView애니메이션

from 학습/iOS 2011/04/07 02:37
UIVew애니메이션의 기능을 사용해 애니메이션 시키는 프로그램을 만든다. 버튼을 누를때마다 다음 4종류의 애니메이션을 수행한다.

1. 안에서부터 확대하며 출현
2.안에서부터 회전확대하며 출현
3. 화면 아래부터 출현
4. 보턴 위치로부터 확대되며 출현

iPhone/iPad에서 애니메이션을 구현하는 것은 "Core Animation"이라 불리는 프레임 워크를 이용한다. Core Animation의 주요 기능으로는 다음 3개가 있다.

*UIView 애니메이션
*레이어 애니메이션
*트랜직션

UIView 애니메이션은 버튼과 뷰등의 유저 인터페이스를 움직이는 애니메이션이다. UIView를 계승하고 있는 오브젝트가 대상이다. 유저 인터페이스의 애니메이션전의 위치, 회전 각도, 투명도와 애니메이션 후의 위치, 회전 각도, 투명도를 설정하는 것으로 그 도중의 상태를 보간해 애니메이션한다. 레이어 애니메이션과 트랜직션에 대해서는 다음장에서 다룬다.

(1) 유저 인터페시의의 어파인 변환과 투명도
=========================
유저 인터페이스에 대해 어파인 변환을 하려면 UIView클래스의 프로퍼티를 사용한다.
어파인 변환이란 도형에 대한 평행이동, 회전, 확대 축소등을 행하는 변환을 말한다.

(중략)

CGAffineTransform 클래스는 어파인 변환에 의해 어느정도, 평행 이동, 회전, 확대 축소하는가를 다루는 클래스다.
평행이동하는 CGAffineTransform 오브젝트를 생성하려면 CGAffineTransformMakeTranslation함수, 회전하는 CGAffineTransform 오브젝트를 생성하려면 CGAffineTransformMakeRotate함수, 확대축소하는 CGAffineTransform 오브젝트를 생성하려면 CGAffineTransformMakeScale함수를 이용한다.

(중략)

회전 후에 확대 축소를하는 등, 복수의 어파인 변환을 합성하고 싶을 떄는 다음 CGAffineTransformTranslate함수, CGAffineTransformRotate함수, CGAffineTransformScale함수를 이용한다.

(중략)

유저 인터페이스의 투명도를 지정하려면 UIView클래스의 alpha 프로퍼티를 사용한다. 10.이 완전히 보이는 상태, 0.0이 완전히 보이지 않는 상태다. 0.0일때는 터치 이벤트도 발생하지 않는다. 뷰가 가지고 있는 서브 뷰에 대해서도 투명도는 반영된다. 뷰의 색만을 투과하고 싶으면 backgroundColor프로퍼티에서 조정한다.

(중략)

이 프로그램에서는 애니메이션 1의 애니메이션 전 상태를 (0.5, 0.5) 축소, 투명도 0.8로 한다.

(중략)

또, 애니메이션 2의 애니메이션 전 상태를 180도 회전하고 (0.5, 0.5) 축소, 투명도 0.8로 한다.

(중략)

이하의 계산으로 도를 라디안으로 변환해 대입한다. M_PI는 파이의 값을 나타내는 상수다.

라디안=도*(M_PI/180)

거기에 애니메이션 3의 애니메이션 ㅓㄴ에 상태를 (0,400) 평행이동, 투명도 0.8)로 한다.

(중략)

(2)UIView애니메이션 설정 개시
===================
UIView 애니메이션을 행하려면 유저인터페이스의 애니메이션 전 위치, 회전 각도, 투명도를 지정한 다음 UIView클래스의 beginAnimations:contex:메소드를 부른다.

(중략)

애니메이션 ID와 파라메터는 애니메이션 개시 시에 불리는 메소드와 애니메이션완료 후 불리는 메소드에 건네지는 인수다. 통지 타겟의 setAnimationRepeatCount:메소드에서는 이것들의 정보를 기초로 어떤 처리를 할 것인지 정한다. 필요 없을 땐 nil을 지정한다.
UIView클래스의 setAnimationDuration:메소드에서 애니메이션 시간, setAnimationCurve:메소드에서 애니메이션 커브, setAnimationRepeatCount:메소드에서 리피트 횟수,  setAnimationRepeatAutoreversed:메소드에서 역방향의 애니메이션을 할지 말지를 지정한다. 애니메이션 커브에서는 점점 빠르게나 점점 느리게를 설정할 수 있다.

(중략)

애니메이션 커브에서는 이하의 상수를 지정한다.

(중략)

(중략)

(3)UIView애니메이션 델리게이트
====================
UIView 애니메이션 델리게이트를 지정하려면 UIView클래스의 setAnimationDelegate:메소드를 사용한다.

(중략)

setAnimationWillStartSelector:메소드에서 UIView애니메이션 개시시ㅇ 불리는 메소드를 지정한다.

(중략)

통지 타겟의 메소드의 서식은 다음과 같다. 인수의 형과 순서가 같은 메소드라면 메소드명은 자유롭게 지정할 수 있다.

(중략)

이 프로그램에서는 ViewAnimationEx오브젝트 자신의 someAnimationWillStart:메소드를 통지 타겟으로 지정했다.

(중략)

통지타겟의 메소드의 서식은 다음과 같다. 인수의 형과 순서가 같은 메소드라면 메소드명은 자유롭게 지정할 수 있다.

(중략)

이프로그램에서는 ViewAnimation오브젝트 자신의 someAnimationDidSto:finished:context:메소드를 통지 타겟으로 지정했다.

(중략)

(4)애니메이션 후의 위치, 회전각도, 투명도
=======================
UIView클래스의 beginAnimations:context:메소드와 commitAnimations메소드의 사이에 애니메이션 후 위치, 회전각도, 투명도를 지정한다. 위치, 회전각도, 투명도의 지정은 commitAnimation 메소드가 불릴때까지 반영되지 않는다.

(5)UIView애니메이션 실행
================
UIView애니메이션을 실행하려면 commitAnimations메소드를 호출한다.

(중략)

(6)프레임 지정에 의한 애니메이션
===================
어파인 변환이 아니라 프레임에 의한 (X좌표, Y좌표, 폭, 높이)의 지정으로 애니메이션 전의 위치와 애니메이션 후의 위치를 지정할 수도 있다.

(후략)

Creative Commons License
2011/04/07 02:37 2011/04/07 02:37

사운드 재생

from 학습/iOS 2011/04/06 17:33

(1)리소스 URL의 생성

============
읽어 올 타겟의 패스로 리소스의 URL을 생성할 때는 NSBundle 클래스의 mainBundle 메소드에서 NSBundle 오브젝트를 취득해 pathForResource:ofType:메소드에서 패스를 생성해 이용한다.

(중략)

pathForResource:ofType:메소드의 인수에는 파일명이 "bgm.wav"의 때는 파일명에 "bgm", 확장자에 "wav" 또는 파일명에 "bgm.wav"와 확장자에 ""를 지정한다.
마지막으로 NSURL클래스의 fileURLWithPath:메소드에서 패스를 URL로 변환한다.


(중략)


(2) 오디오 플래이어 생성
==============
사운드의 재생을 할 오디오 플레이어를 생성할 때는 AVAudioPlayer클래스를 사용한다 alloc으로 메모리를 확보후 initWihtContentsOfURL:error:메소드로 생성한다.

(중략)

====
[컬럼] 포인터의 포인터
====
포인터의 어드레스를 한번 더 포인터에 격납하는 것이 가능하며 이 포인터를 "포인터의 포인터"라 부른다. 포인터의 포인터를 선언할 때는 다음과 같은 서식으로 선언한다.

형** 변수명;

거기에 포인터의 포인터의 포인터를 만드는 것도 가능하나 통상 사용하진 않는다. 포인터의 포인터의 잇점은 참조형의 반환값을 함수의 반환값이 아닌 인수경유로 취득할 수 있다는 것이다.

AVAudioPlayer클래스의 initWithContentsOfURL:error:메소드의 인수 error도 에러 정보를 포인터의 포인터"(NSError**)"로 취득할 수 있다. NSError오브젝트를 선언 후 그 변수의 포인터의 포인터를 대응하는 메소드의 인수에 넘긴다. 임의의 변수의 포인터는 "&변수명"으로 나타낸다. 이것으로 에러시에는 error오브젝트에 NSError오브젝트를 대입되어 돌아온다.
initWithContentsOfURL:error:메소드의 에러 정보를 콘솔에 보내는 프로그램은 다음과 같다.

(중략)
----


(3) BGM의 재생과 정지
=============
오디오 플레어가 사운드를 재생중인가 어떤가 살펴보려면 AVAudioPlayer클래스의 playing프로퍼티를 사용한다. 이번에는 정지 중일 때는 사운드를 재생하고, 재생중일 때는 사운드를 정지한다.
사운드를 재생하려면 AVAudioPlayer클래스의 numberOfLoops프로퍼티에서 루프 회수를 지정해 currentTime프로퍼티에서 재생위츠를 지정하고 play메소드로 재생을 개시한다. 사운드를 정지하려면 stop메소드를 부른다.

(중략)

(4)SE 재생
=======
SE재생은 정지중일 때는 재생하고, 재생중일 때는 재생위치를 처음으로 돌린다.

(5) 오디오 플레이어의 볼륨 조작
===================
오디오 플레이어의 볼륨을 조작하려면 AVAuidoPlayer 클래스의 volume 프로퍼티를 사용한다. 오디오 플레이어의 볼륨의 최최값은 1.0으로 사운드 파일당의 볼륨의 조정에 이용한다. 단말의 볼ㄹㅁ 조작에 대해서는 다음장에서 다룬다.

(중략)

=======
[컬럼] 바이브레이션
========
iPHONE에서 바이브레이션을 하려면 AudioToolbox프레임 워크를 추가해 "Audio/AudioServices.h"를 임포트해 AudioServicePlayeSystemSound함수를 부른다

(후략)
Creative Commons License
2011/04/06 17:33 2011/04/06 17:33
6-3-1 가속도와 단말의 방향 취득 프로그램 구성
==========================

단말 내장의 가속도 센서를 이용해서 가속도와 단말이 향한 방향을 취득해 표시하는 프로그램을 만든다.
표시하는 정보는 다음과 같다.
가속도 센서는 모든 iOS단말에 이용 가능하다.

X축 가속도 (m/s)
Y축 가속도  (m/s)
Z축 가속도 (m/s)

단말 화면이 위를 향해 정지 한 상태에서는 X축 가속도와 Y축 가속도가 0.0, Z축 가속도가 -9.8이 된다. 이것은 지면을 향한 중력(9.8m/s)가 작용하기 때문이다.

(중략)

(1) 가속도 통지 개시
============
가속도의 통지를 개시하려면 UIAccelerometer 클래스를 이용한다. UIAccelerometer 클래스의 sharedAccelerometer클래스에서 UIAccelerometer 오브젝트를 취득한다.

(중략)

UIAccelerometer 클래스의 주요 프로퍼티는 다음과 같다. 이번에는 0.1초 마다 AccelerometerEx 클래스 자신에 가속도를 통지하도록 지정한다.

 (중략)

(2) 가속도 센서 델리게이트
===============
가속도 센서의 이벤트 통지 타겟에는  UIAccelerometerDelegate  프로토콜을 구현한 오브젝트를 지정한다. UIAccelerometerDelegate 프로토콜이 가진 메소드는 다음과 같다.

(중략)

가속도는 UIAcceleration 형의 값으로 UIAcceleration 클래스는 다음 4개의 프로퍼티를 가진다. UIAccelerationValue형과 NSTimeInterval형은 double형이다.

(중략)

(3) 가속도에 로우패스 필터 걸기
==================
acceleration.x, acceleration.y, acceleration.z 가 가속도 센서로부터 취득한 가속도의 값이다. 이 값을 그대로 이용해도 좋으나 그대로는 가속도 센서의 순간적인 데이터 변화의 영향을 받아 수치가 안정되어있지 않으므로, 일반적으로 로우패스필터를 통해 안정된 값을 이용한다.
구체적으로는 다음과 같은 "현재의 가속도*0.1+전회의 가속도*0.9"를 계산해 전회의 가속도로부터 스무드하게 현재의 가속도에 가까워지도록 한다.

(중략)

단말 흔들기등 순간적인 움직임을 계산하고 싶은 경우는 현재의 가속도로부터 로우패스 필터의 값을 뺀 값을 이용한다.

(중략)


(4)단말이 향한 방향의 통지 개시
==================
단말 회전시에 향한 방향을 취득하려면 UIDevice클래스와 NSNotificationCenter 클래스를 사용한다. UIDevice 크래스의 currentDevice메소드에서 UIDevice 오브젝트를 취득해 beginGeneratingDeviceOrientationNotification 메소드로 단말이 향한 방향의 통지를 시작한다.

(중략)

다음, NSNotificationCenter 클래스의 defaultCenter 메소드에서 NSNotificationCenter 오브젝트를 취득해 addObserver:selector:name:object:메소드로 단말이 향한 방향의 통지 타겟 오브젝트와 메소드를 지정한다.

(중략)

SEL은 메소드의 참조를 유지하는 형으로 "@selector(메소드명)"으로 통지 타겟의 메소드 명을 지정한다. 통지 타겟의 메소드 서식은 다음과 같다. 인수의 형과 순서가 같은 메소드라면 메소드 명은 자유롭게 지정할 수 있다.

(중략)

이 프로그램은 AcceleromaterEx 오브젝트 자신의 didRotate:메소드를 통지 타겟으로 지정하고 있다.

selector:@selector(didRotate:)

통지의 종류에는 단말이 향한 방향 변경의 통지를 의미하는 "UIDeviceOrientationDidChangeNotification"을 지정한다.


(5) 단말이 향한 방향 취득
==============
didRotate:메소드에 통지된 NSNotification 오브젝트로부터 단말이 향한 방향을 취득한다. NSNotification 클래스의 object 메소드로 통지의 발신원의 UIDevice 오브젝트를 취득해 orientation 프로퍼티로 단말의 방향을 받아들인다.

(중략)

단말이 향한 방향에는 다음과 같은 상수가 대입되어있다.


(중략)

UIViewController 클래스의 shouldAutorotateToInterfaceOrientation:메소드도 단말 회전시에 불리지만 이것은 화면이 회전하기 전에 불리는 메소드가 된다.




Creative Commons License
2011/04/02 15:04 2011/04/02 15:04
(1) 로케이션 매니저 생성
==============
위치정보 또는 방위정보를 취득하려면 우선 처음에 CLLocationManager 오브젝트를 생성한다. alloc으로 메모리를 확보후 init 메소드로 생성한다. 주요 프로퍼티는 다음과 같다.

(중략)

(2) 위치 정보 통지의 개시와 정지
==================
위치정보 통지가 가능한지 어떤지 조사하려면 CLLocationManager 오브젝트의 locationServicesEnabled 프로퍼티를 사용한다.

(중략)

위치 정보의 통지를 개시하려면 startUpdatingLocation 메소드를 사용한다.

(중략)

위치 정보 통지를 정지하려면 stopUpdatingLocation 메소드를 사용한다.

(중략)

(3) 방위 정보 취득의 개시와 정지
===================
방위 정보 통지가 가능한가 어떤가 조사하려면 CLLocationManager 오브젝트의 headingAvailable 메소드를 사용한다.

(중략)

방위 정보의 통지를 개시하려면 startUpdatingHeading메소드를 사용한다.
(중략)

방위 정보의 통지를 정지하려면 stopUpdatingHeading 메소드를 사용한다.

(중략)

(4) 로케이션 매니저의 델리게이트
===================
로케이션 매니저의 이벤트 통지 타겟은 CLLocationManagerDelegate 프로토콜을 구현한 오브젝트를 지정한다. CLLocationManagerDelegate프로토콜을 가진 메소드는 다음과 같다.

(중략)

CLLocation 오브젝트의 coordinate프로퍼티에서 CLLocationCoordinate2D형의 값을 취득한다. CLLocationCoordinate2D형의 구조체는 위도latitude와 경도longitude의 값을 유지한다. CLLocationDegrees형은 double형과 같다.

(중략)

단말 설정으로 위치정보의 취득이 불가능한 경우는 NSError 오브젝트의 code프로퍼티에 kCLErrorDenied가 들어간다.

(중략)

CLHeading 오브젝트의 trueHeading 프로퍼티가 진북의 방위를 나타내는 값(0.0~360.0)이다. CLLocationDerection형은 double과 같다.

========
컬럼 : 진북과 자북
========
진북은 지구 지축의 북, 자북은 방위 자석이 가리키는 북이다. 진북과 자북은 장소에 따라 어긋날 수 있다. 이 어긋남을 자기편각이라 부르고 동경에서는 약 7도 어긋난다.
진북이 아니라 자북의 방위를 알려면 magneticHeading 프로퍼티를 사용한다.

 CLLocationDerection magneticHeading : 자북을 나타내는 값(0.0~360.0)

Creative Commons License
2011/04/01 23:47 2011/04/01 23:47

과거 Frameworks 에서 오른클릭으로 Add하던 것에서
프로젝트 선택한 뒤 오른쪽 탭에서 Build Phases -> 오른쪽 바들 가운데 Link Binary with Libraries를 열고 +를 눌러 추가.
사용자 삽입 이미지
Creative Commons License
2011/04/01 16:11 2011/04/01 16:11

Xcode 4 업데이트

from 학습/iOS 2011/03/10 16:38
사용자 삽입 이미지


새벽에 iOS 4.3이 공개됐다. 업데이트 하고 보니 Xcode 4도 공개됐다.

그래서 업데이트

사용자 삽입 이미지


아. 이런 Xcode 3.x와 달라진 게 좀 있다. 공부할 땐 아무리 간단한 변경이라도 머리아픈 경우가 있을텐데..

뭐 잘 되겠지 ㅋ



으악... Instruments 연동 테스트하는 거 모르겠다 ;ㅁ;


찾았다.. 실행 버튼 누르고 나오는 메뉴에 숨겨져있군.

사용자 삽입 이미지

Creative Commons License
2011/03/10 16:38 2011/03/10 16:38

Xcode 4 UNIVERSAL...

from 학습/iOS 2011/03/10 16:03

샘플코드에선 각각 사이즈를 지정해줬는데, 걍 화면 크기 구해서 알아서 들어가게 해본 것.

게다가 Xcode 4로 가면서 기기별로 나눠져있던 부분이 하나로 합쳐져서 정리되어있으므로 각각 상속해서 오버라이드 각각 해주기 싫음 이렇게 해줄 필요가 있을지도. 너무나 당연(?)하지만.. 뭐 배울때 따로 배운걸 워쩌겠..ㅋㅋㅋㅋ


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    // Override point for customization after application launch.

    CGRect viewBound=[[UIScreen mainScreen]bounds]; //메인 화면 사이즈 구하기

    

    

    _viewCtl=[[LocationEx alloc] init];

    [_viewCtl.view setFrame:CGRectMake(0, 20, viewBound.size.width, viewBound.size.height)];

    [_window addSubview:_viewCtl.view];

    [_window makeKeyAndVisible];

    return YES;

}


틀림 할 수 없지 뭐. 케세라세라.

Creative Commons License
2011/03/10 16:03 2011/03/10 16:03

카메라와 앨범

from 학습/iOS 2011/02/28 15:56
(1)카메라와 포토 앨범의 이용가능 체크
===================================
카메라와 포토앨범에 액세스하기 전에 이용가능한가 어떤가를 체크한다. 체크하려면 UIImagePickerController클래스의 isSourceTypeAvailable:메소드를 사용한다.  또 포토 앨범은 현죠ㅗㄴ하는 모든 단말에서 이용가능하지만 카메라는 단말에 따라 다르다.

(중략)

소스 타입에는 다음 상수를 지정한다.

(중략)

(2) 이미지 피커의 생성
=====================
카메라 또는 포토 앨범으로 부터 화상을 읽어들이려면 UIIMagePickerCOntroller클래스를 사용한다. alloc으로 메모리를 확보후 init메소드로 생성한다. 주요 프로퍼티는 다음과 같다.
소스 타입은 표 6-1-1과 같다.

(중략)

델리게이트 형의 [id<UINavigationControllerDelegate, UIImagePickerControllerDelegate>]는 델리게이트로 지정한 오브젝트가 UINavigationControllerDelegate 프로토콜과 UIImagePickerControllerDelegate 프로토콜의 양방을 구현할 필요가 있음을 나타낸다. 구현 해야할 프로토콜이 2개 존재하는 것에는 이미지 피커가 네비게이션을 계승하고 있기 때문이다.


(3) 내비게이션의 델리게이트
===========================
내비게이션의 이벤트 통지 타겟에는 UINavigationControllerDelegate 프로토콜을 구현한 오브젝트를 지정한다.
UINaviationControllerDelegate 프로토콜을 가진 메소드는 다음과 같다.

(중략)

이번은 UINavigationControllerDelegate 프로토콜의 구현 선언만 한다. UINavigationControllerDelegate 프로토콜의 메소드는 모든 옵션 메소드로 이번에는 처리할 필요는 없으므로 메소드를 구현하진 않고 있다.

(4) 이미지 피커의 델리게이트
============================
이미지 피커의 이벤트 통지타겟에는 UIImagePickerControllerDelegate 프로토콜을 구현한 오브젝트를 지정한다. UIImagePickerControllerDelegate 프로토콜을 가진 메소드는 다음과 같다.

(중략)

미디어 정보로부터 이미지를 취득하려면 키[UIImagePickerControllerOriginalImage]의 값을 취득한다.

UIImage* image=[info objcetForKey:UIImagePickerControllerOriginalImage];

(중략)

(5) 뷰 콘트롤러의 뷰 열기
========================
뷰 콘트롤러의 뷰를 열기위해선 UIViewCOntroller 클래스의 presentModalViewController:aniated:메소드를 호출한다. 이번에는 이미지 피커를 열고있다.

(중략)

(6) 뷰 콘트롤러의 뷰 닫기
=======================
뷰 콘트롤러의 뷰를 닫기위해서는 UIViewController클래스의 dismissModalViewControllerAnimated:메소드를 호출한다. 이번에는 이미지 피커를 닫는다.

(중략)

(7) 이미지를 포토 앨범에 쓰기
===============================
이미지를 포토앨범에 써넣기를 실행하려면 UIImageWriteToSavedPhotosAlbum 함수를 이용한다.

(중략)

SEL은 메소드 참조를 가지는 형으로 [@selector(메소드명)]에 통지 타겟의 메소드명을 지정한다. 통지 타겟의 메소드의 서식은 다음과 같다. 인수의 형과 순서가 같은 메소드라면 메소드 명은 자유로이 지정할 수 있다.

(중략)

이 프로그램에서는 CameraEx오브젝트 자신의 finishExport:메소드를 통지 타겟으로서 지정하고 있다.

@selector(finishExport:didFinishSavignWithError:contextInfo:)

Creative Commons License
2011/02/28 15:56 2011/02/28 15:56

HTTP통신

from 학습/iOS 2011/02/24 16:30
(1) GET에 의한 HTTP통신
========================
HTTP통신을 하려면 처음 NSURLRequest오브젝트를 생성한다. 타임아웃(디폴트 4분)을 설정하지 않은 때는 RequestWithURL:메소드, 타임아웃을 설정한 때는 requestWithURL:cachePolicy:timeoutInterval:메소드를 사용한다.

(중략)

캐쉬 폴리시에는 NSURLRequestUseProtocolCachePolicy(프로토콜 폴리시를 이용)을 설정한다. 타임아웃 시간은 초단위로 설정한다.
URL에는 NSURL오브젝트를 넘긴다. NSURL오브젝트는 NSURL클래스의 URLWithString메소드를 생성한다.

(중략)

다음으로 NSURLConnection클래스의 connectionWithRequest:delegate:메소드로 HTTP통신을 개시한다.

(중략)
여기서 지정한 델리게이트에 대해서 수신 데이터와 통신 결과의 통지를 한다. 이 프로그램에서는 HttpEx 오브젝트 자신을 델리게이트로 지정한다.


(2) NSURLConnection 델리게이트
================================
NSURLConnection 델리게이트를 가진 메소드는 다음과 같다.

(중략)


이 프로그램에서는 HTTP통신의 개시시에 NSMutableData오브젝트를 생성해, 데이터 수신시에 NSMutableData 오브젝트에 데이터를 추가해 HTTP통신의 성공시에 수신 데이터를 문자열로 변환해 텍스트 필드에 대입한다. HTTP통신 실패시에는 "통신에러" 문자열을 텍스트 필드에 대입한다.

(3) 가변 길이 바이트 배열
=======================
NSMutableData클래스는 길이가 가변하는 바이트 배열 클래스다. 생성시에는 data메소드를 사용한다.

(중략)

바이트 배열을 추가할 때는 appendData:메소드를 사용한다.


(중략)


(4) 인디케이터
==============
현재 통신중인 것을 나타내기 위해 빙글빙글 도는 인디케이터를 표시한다. 4장[4-6 WEB뷰]에서는 타이틀 바에 표시했지만 이번에는 뷰 상에 배치한다.

(그림 생략)

인디케이터를 생성하려면 UIActivityIndicatorView 클래스를 사용한다. alloc으로 메모리 확부  후 init메소드로 생성한다. 인디케이터의 주요 프로퍼티는 다음과 같다.


(중략)

인디케이터 스타일에는 다음과 같은 상수를 지정한다. 이번에는 희고 큼을 지정했다.

(중략)

hidesWhenStopped 프로퍼티에 YES를 대입하는 것으로 인디케이터의 애니메이션 정지시에 표시하지 않게 된다.
인디케이터의 애니메이션을 개시시키려면 startAnimating메소드, 정지시키려면 stopAnimating 메소드를 사용한다.

(후략)



==============================
[컬럼] POST에 의한 HTTP 통신
==============================
POST에 의한 HTTP통신을 하려면 setHTTPMethod:메소드에서 "POST"를 지정해 setHTTPBody:메소드에 업로드 하는 송신데이터를 지정한다.

(중략)

구체적으로는 다음과 같이 기술한다.

//POST에 의한 HTTP통신
-(void)http2data:(NSString*)url delegate:(id)delegate body:(NSData*)body {
     NSMutableURLRequest* request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
     [request setHTTPMethod:@"POST"];
     [request setHTTPBody:body];
     [NSURLCOnnection connectionWithRequest:request delegate:delegate];
}

또, HTTPBody를 지정하면 타임아웃의 초수 지정이 반영되지 않고 4분이 됩니다. 타임아웃 하고 싶은 경우는 외부 타이머를 사용해 NSURLConnection오브젝트의 cancel메소드를 불러 명시적으로 정지할 필요가 있습니다.

(후략)



Creative Commons License
2011/02/24 16:30 2011/02/24 16:30

프리퍼런스 저장

from 학습/iOS 2011/02/22 16:22
(1) 프리퍼런스 저장
==================
프리퍼런스 저장을 하려면 NSUserDefaults오브젝트를 사용한다. NSUserDefaults클래스의 standardUserDefaults메소드에서 NSUserDefaults오브젝트를 취득한다.

(중략)

NSUserDefaults오브젝트에 키와 값의 조합으로 저장하는 정보를 지정한다. 값의 형에 따라 이용할 메소드가 달라진다.

(중략)

마지막에 synchronize메소드를 불러 지정한 값이 저장된다.

(중략)

이번에는 텍스트 필드의 텍스트를 저장한다. NSString형 등의 오브젝트형의 값은 setObject:메소드로 지정한다.

NSUserDefault* pref=[NSUderDefaults standardUserDefaults];
[pref setObject:_textField.text forKey:@"text"];
[pref syncronize];

(2)프리퍼런스 읽어오기
=====================
프리퍼런스의 읽어오기를 하려면 NSUserDefaults오브젝트를 이용한다. 취득 메소드의 인수에 키를 지정하는 것으로 값을 얻을 수 있다. 값의 형에 따라 이용할 메소드가 달라진다.

(중략)

이번에는 stringForKey:메소드로 문자열을 취득하고 있다. 보존하고있는 값이 없으면 nil이 반환된다.

NSUserDefaults* pref=[NSUserDefaults standardUserDefaults];
_textField.text=[pref stringForKey:@"text"];

Creative Commons License
2011/02/22 16:22 2011/02/22 16:22
(1) 문자열 바이트 배열 변환
=========================
문자열을 바이트 배열로 변환하려면 NSStirng 클래스의 dataUsingEncoding:메소드를 사용한다. NSData오브젝트는 byte배열을 가진 오브젝트다.

(중략)

인코딩에 지정한 주요 상수는 다음과 같다.

인코딩에 지정하는 주요 상수       의미
NSUTF8StringEncoding              UTF-8
NSShiftJISStringEncoding           Shift-JIS
NSJapaneseEUCStringEncoding EUC-JP
표 5.-1-1 인코딩에 지정하는 주요 상수


문자열의 바이트 배열 변환 메소드를 한데모으면 다음과 같이 된다.

-(NSData*)str2data:(NSStirng*)str{
     return [str dataUsingEncoding:NSUTF8StringEncoding];
}

(2) 바이트 배열 문자열 변환
=========================
바이트 배열을 문자열로 변환하려면 NSString 클래스의 initWithData:encoding:메소드를 사용한다.

(중략)

인코딩에 지정된 상수는 표 5-1-1과 같다. 바이트 배열의 문자열 변환을 메소드로 한데 모으면 다음과 같이 된다.

-(NSStirng*)data2str:(NSData*)data{
     return [[[NSStirng alloc] initWithData:data
          encoding:NSUTF8StringEncoding] autorelease];
}


(3) 바이트 배열의 저장
=====================
바이트 배열을 파일로 저장하려면 NSData클래스의 writeToFile:atomically:atomically:메소드를 사용한다.

(중략)

저장타겟의 패스를 생성하려면 NSHomeDiectiry 함수에서 iPhone/iPad 앱의 홈폴더를 취득해, stringByAppendingPathComponent:메소드에서 :Documents"와 파일명을 추가한다.
tmp폴더에 저장할 때는 "Documents" 대신 "tmp"를 지정한다.

(중략)

문자열 추가시에 stringByAppendigPathComponent:메소드를 쓰면 패스의 세퍼레이터"/"가 자동으로 부가된다.

path=[@"/tmp"  stringByAppendigPathComponent:@"test.txt"]; //->@"/tmp/test.txt"
path=[@"/tmp/" stringByAppendigPathComponent:@"test.txt"]; //->@"/tmp/test.txt"
path=[@"/"       stringByAppendigPathComponent:@"test.txt"]; //->@"/test.txt"
path=[@""         stringByAppendigPathComponent:@"test.txt"]; //->@"test.txt"

바이트 배열의 저장을 메소드에 모으면 다음과 같이 된다.

-(BOOL)data2file:(NSData*)data fileName:(NSString*)filename {
     NSString* path=[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
     path=[path stringByAppendigPathComponent:fileName];
     return [data writeToFile:path atomically:YES];
}


(4) 바이트 배열의 불러오기
========================
바이트 배열을 파일로부터 불러오려면 NSData 클래스 dataWithContentsOfFile: 메소드를 사용한다

(중략)

불러들일 타겟 패스를 생성하려면 NSHomeDirectory 함수로 iPhone/iPad 앱의 홈 폴더를 취득해 stringByAppendigPathComponent:메소드로 "Documents"와 파일명을 추가한다. tmp폴더로부터 불러올 때는 "Documents"대신 "tmp"를 지정한다.
바이트 배열 읽어오기를 메소드에 모으면 다음과 같이 된다.

-(NSData*)file2data:(NSString*)fileName {
    NSString* path=[NSHomeDirectory() stringByAppendigPathComponent:@"Documents"];
    path=[path stringByAppendignPathComponent:fileName];
    return [NSData dataWithContentsOfFile:path];
}






----------------------

Constants

NSASCIIStringEncoding

Strict 7-bit ASCII encoding within 8-bit chars; ASCII values 0…127 only.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSNEXTSTEPStringEncoding

8-bit ASCII encoding with NEXTSTEP extensions.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSJapaneseEUCStringEncoding

8-bit EUC encoding for Japanese text.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUTF8StringEncoding

An 8-bit representation of Unicode characters, suitable for transmission or storage by ASCII-based systems.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSISOLatin1StringEncoding

8-bit ISO Latin 1 encoding.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSSymbolStringEncoding

8-bit Adobe Symbol encoding vector.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSNonLossyASCIIStringEncoding

7-bit verbose ASCII to represent all Unicode characters.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSShiftJISStringEncoding

8-bit Shift-JIS encoding for Japanese text.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSISOLatin2StringEncoding

8-bit ISO Latin 2 encoding.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUnicodeStringEncoding

The canonical Unicode encoding for string objects.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSWindowsCP1251StringEncoding

Microsoft Windows codepage 1251, encoding Cyrillic characters; equivalent to AdobeStandardCyrillic font encoding.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSWindowsCP1252StringEncoding

Microsoft Windows codepage 1252; equivalent to WinLatin1.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSWindowsCP1253StringEncoding

Microsoft Windows codepage 1253, encoding Greek characters.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSWindowsCP1254StringEncoding

Microsoft Windows codepage 1254, encoding Turkish characters.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSWindowsCP1250StringEncoding

Microsoft Windows codepage 1250; equivalent to WinLatin2.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSISO2022JPStringEncoding

ISO 2022 Japanese encoding for email.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSMacOSRomanStringEncoding

Classic Macintosh Roman encoding.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUTF16StringEncoding

An alias for NSUnicodeStringEncoding.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUTF16BigEndianStringEncoding

NSUTF16StringEncoding encoding with explicit endianness specified.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUTF16LittleEndianStringEncoding

NSUTF16StringEncoding encoding with explicit endianness specified.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUTF32StringEncoding

32-bit UTF encoding.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUTF32BigEndianStringEncoding

NSUTF32StringEncoding encoding with explicit endianness specified.

Available in iOS 2.0 and later.

Declared in NSString.h.

NSUTF32LittleEndianStringEncoding

NSUTF32StringEncoding encoding with explicit endianness specified.

Available in iOS 2.0 and later.

Declared in NSString.h.

====================================
[컬럼] 리소스로부터 바이트 배열 읽어오기
====================================

리소스로부터 이미지를 읽어오려면 UIImage의 imageNamed:메소드를 사용하지만, 바이트 배열을 읽어오려면 NSData클래스의 dataWithContentsOfFile:메소드를 사용한다.

(중략)


읽을 위치의 패스로 리소스의 패스를 지정할 때는 NSBundle클래스의 mainBundle메소드에서 NSBundle오브젝트를 취득해 pathForResource:ofType:메소드에서 패스를 생성해 이용한다


(중략)


pathForResource:ofType:메소드의 인수에는 파일명이 "test.txt"일 때의 파일명에 "test"와 확장자에 "txt", 아니면 파일명에 "test.txt"와 확장자에 ""를 지정한다. 리소스로부터 바이트 배열을 읽어오는 메소드로 정리하면 다음과 같다.

-(NSData*)res2data:(NSString*)res {
     NSString* file=[[NSBundle mainBundle] pathrForResource:res ofType:@""];
     return [NSData dataWithContentsOfFile:file];
}

Creative Commons License
2011/02/22 12:25 2011/02/22 12:25

폰트 패밀리 명 취득

from 학습/iOS 2011/02/21 14:04
(1) 폰트 패밀리명 취득
=======================
단말에서 사용가능한 폰트 패밀리명을 취득하려면 UIFont 클래스의 familyNames 메소드를 사용한다.

(중략)

(2) NSArray 오브젝트의 소트
==========================
NSArray 오브젝트의 소트를 하려면 NSArray 클래스의 sortedArrayUsingSelector:메소드를 사용한다.

(중략)

comparator에는 비교용 메소드를 지정한다. 이 프로그램에서는 NSString 클래스의 compare:메소드를 지정했다.

(중략)

반환값은 다음의 상수가 반환된다. 이것으로 ABC순으로 소트 된다.

compare:메소드 반환값       의미
NSOrderedAscending(-1)    전
NSOrderedSame(0)             같음
NSOrderedDescending(1)    후
표 4-9-1 compare:메소드의 반환값

(3) 폰트명의 취득
================
폰트 패밀리명으로부터 그 패밀리에 속한 폰트명을 취득하려면 UIFont클래스의 fontNamesForFamilyNmae:메소드를 사용한다.

(중략)

(4) 피커뷰의 생성
=================
피커뷰를 생성하려면 UIPickerView클래스를 사용한다. alloc으로 메모리를 확보 후 init메소드로 생성한다. 주요 프로퍼티는 다음과 같다.

(중략)

(5)피커뷰의 델리게이트
=====================
피커 뷰의 이벤트 통지 타겟에는 UIPickerViewDelegate 프로토콜을 구현한 오브젝트를 지정한다. UIPickerViewDelegate 프로토콜의 소유주인 메소드는 다음과 같다.

(중략)

이프로그램에서는 행의 높이로 30을 반환한다. 셀의 생성에서는 UIView오브젝트를 생성해 그것에 레이블을 추가해 반한한다. UIView오브젝트는 alloc으로 메모리 확보후 initWithFrame:메소드로 생성한다.

(후략)
Creative Commons License
2011/02/21 14:04 2011/02/21 14:04
(1) 내비게이션 컨트롤러 생성
===========================
내비게이션 컨트롤러를 생성하려면 UINavigationController클래스를 사용한다. alloc으로 메모리 확보후 init메소드로 생성한다. 내비게이션의 1개 아래 계층으로 이동하는 것에는 pushViewController:animated:메소드를 사용한다.

(중략)

(2) 파일과 폴더 계층의 정의
=========================
NavigationEx클래스를 init메소드로 생성한 때 파일과 폴더 계층의 정의를 한다. 파일은 NSString형, 폴더는 NSDictionary형을 사용한다.

종류    데이터 형           내용
파일    NSString형         값은 파일명
폴더    NSDictionary형   키는 파일명, 값은 폴더에 포함된 파일과 폴더의 배열
표 4-8-1 파일과 폴더의 계층 정의

다음 그림과 같은 파일과 폴더의 계층을 정의하려면 다음과 같이 기술한다. 파일과 폴더의 계층을 정의 하면 마지막에 테이블에 표시할 폴더를 _folder 변수에 대입한다.

(중략)

(3) 내비게이션 바의 타이틀 지정
==============================
내비게이션 바의 타이틀을 지정하려면 UIViewController클래스의 title 프로퍼티에서 지정한다. 이번에는 _folder 변수의 키를 지정한다.

(중략)

(4) 내비게이션 바의 버튼의 추가
내비게이션 바의 버튼을 생성하려면 UIBarButtonItem클래스를 사용한다. alloc으로 메모리를 확보후 init메소드로 생성한다.

(중략)

스타일에는 다음 상수가 지정된다. 통지 타겟의 오브젝트와 메소드의 지정은 UIButtuon클래스와 같다.
(중략)

SEL은 메소드의 참조를 가지는 형으로 [@selector(메소드명)]으로 통지 타겟의 메소드명을 지정한다. 통지 타겟의 메소드의 서식은 다음과 같다. 인수의 형과 순서가 같은 메소드라면 ㅔㅁ소드명은 자유롭게 지정할 수 있다.

(중략)

이 프로그램에서는 NavigationEx 오브젝트 자신을 clickButton:메소드를 통시 타겟으로 지정하고 있다.

action:@selector(clickButton:)

(5)1단 아래 계층으로 이동
========================
1단 아래 계층으로 이동하려면 애플리케이션 델리게이트에서도 이용한 pushViewController:animated:메소드를 사요한다. 새로운 NavigationEx오브젝트를 생성해, level과 page를 저정해 이동한다.

아래 계층에는 내비게이션 바의 왼쪽에 윗단 계층으로 돌아가는 버튼이 표시된다. 이것 이외의 방법으로 위의 계층으로 돌아가려면 popViewControllerAnmated:메소드를 사용한다.

(중략)

가장 위의 계층까지 돌아가려면 popToRootViewControllerAnmated:메소드를 사용한다.

(중략)

(6)테이블 뷰의 생성
==================
테이블 뷰를 생성하려면 UITableView클래스를 사용한다. alloc으로 메모리를 확보하고 init메소드로 생성한다. 주요 프로퍼티는 다음과 같다.

(중략)

(7) 테이블 뷰의 델리게이트
=========================
테이블 뷰의 이벤트 통지 타겟에는 UITableViewDelegate 프로토콜과 UITableViewDataSource 프로토콜을 구현한 오브젝트 를 지정한다. UITableViewDelegate 프로토콜에서는 테이블의 표시 관련의 처리를 하고 UITableViewDataSource프로토콜에서는 테이블의 데이터 관련 처리를 한다.
UITableViewDelegate프로토콜이 가진 주요 메소드는 다음과 같다

(중략)

액세서리 버튼은 상세 버튼등의 셀에 추가 하는 보조 버튼이다.
이 프로그램에서는 셀 높이로 50을 반환해 셀또는 액세서리 버튼을 클리한 때 0계층째은 1게층 아래로 이동하고 1계층 때는 얼럿을 표시하고 있다.
UITableViewDataSource프로토콜이 가진 주요 메소드는 다음과 같다. 이번에는 셀수로서 _itmes.count를 반환한다.

(중략)

(8) 테이블의 셀 생성
==================
테이블의 셀을 만드려면 UITableViewCell클래스를 사용한다. alloc으로 메모리를 확보하고 init메소드로 생성한다. 내비게이션의 1ㄱ단 아래 계층으로 이동하려면 pushViewController:aniated:메소드를 사용한다.

(중략)

스타일에는 다음의 상수를 지정한다. 화면과 라벨의 표시위치가 바뀐다.

(중략)
reuseIdentifier에는 임의 재이용 ID를 지정한다. 재이용 ID를 지정해 생성하면 다음번 UTableView클래스의 dequeueReusableCellWithIdentifier:메소드에서 같은 셀을 취득할 수 있게 된다.

(중략)

셀에 표시하는 텍스트를 편집하려면 UITableViewCell클래스의 texLabel 프로퍼티를 편집한다. 상세 텍스트를 지정하려면 detailTextLable프로퍼티, 이미지를 지정하려면 imageView프로퍼티를 편집한다.

또 자유로이 컴포넌트를 배치하고 싶으면 contetView프로퍼티와 backgroundView프로퍼티를 편지합니다. 셀에 액세서리를 추가하려면  다음 프로퍼티를 사용한다.

(중략)

액세서리 타입은 다음 상수를 지정한다.

(중략)

이 프로그램에서는 텍스트에 파일명 또는 폴더명을 지정해 폴더 시는 액세서리로 상세 버튼을 추가한다.

(9) 테이블의 셀 선택 해제

테이블 셀의 선택 해제를 하는 것은 UTableView클래스의 deselectRowAtIndexParh:anmated 메소드를 사용한다.

(중략)

셀의 위치에는 UITableView 클래스의 indexPathForSeectedROw메소드에서 취득한 현재 선택중의 셀 위치를 지정한다
(후략)




Creative Commons License
2011/02/15 18:59 2011/02/15 18:59

맵뷰 생성

from 학습/iOS 2011/02/14 16:45
(1)맵뷰 생성
============
맵뷰를 생성하려면 MKMapView클래스를 사용한다. alloc으로 메모리 확보후, init메소드로 생성한다. 주된 프로퍼티는 다음과 같다.

(중략)

지도 타입에는 다음 상수를 지정한다

(중략)

이 프로그램에서는 MapViewEx틀래스 자신에 MKMapViewDelegate 프로토콜을 구현해 델리게이트로 지정하고 있다.

(2) 위치 값 준비
===============
위치 값은 CLLocationCoordinate2D형의 값으로 유지한다. latitude에 위도, longitude에 경도를 지정한다. 이번에는 **를 지정했다.

typedef struct {
     CLLocationDegrees latitude;
     CLLocationDegrees longitude;
} CLLocationCoordinate2D;

=================================================
[컬럼] 경도와 위도
'위도'(latitue)라는 것은 적도를 기점(0도)으로 해서 북으로 +90도(북위) 남으로 -90(남위)의 각도를 표시하는 것, '경도'(longitude)라는 건 영국의 구 그리니치 천문대를 지나는 자오선을 기점(0도)로 해서 동으로 180도(동경), 서로 180도(서경)의 각도를 표시하는 것이다
=================================================


(3) 줌 값의 준비
===============
줌 값은 MKCoordinateSpan형 값으로 유지한다. latiudeDelta에 지도상에 표시되는 남북의 거리, longitudeDelta에 지도상에 표시되는 동서의 거리를 지정한다. 이번엔 0.01을 지정

type struct {
     CLLocationDegrees latitudeDelta;
     CLLocationDegrees longitudeDelta;
} MKCoordinateSpan;

(4) 줌과 위치의 지정
===================
맵뷰에 줌과 위치 값을 지정하는 것은 우선 MKCoordinateRegion형의 변수에 줌과 위치값을 대입한다. center는 위치, span은 줌값의 값이다.

typedef struct {
     CLLocationCoordinate2D center;
     MKCoordinateSpan span;
} MKCoordinateRegion;

이 값을 MKMapView클래스의 setRegion:animated:메소드에 사용한다.


(중략)

(5) 맵뷰의 델리게이트
====================
맵뷰의 이벤트 통지 타겟에는 MKMapViewDelegate 프로토콜을 구현한 오브젝트를 지정한다. MKMapViewDelegate 프로토콜의 소유주인 메소드는 다음과 같다.

(후략)
Creative Commons License
2011/02/14 16:45 2011/02/14 16:45

Web뷰

from 학습/iOS 2011/02/11 13:39
(1)Web뷰 생성
=============
Web뷰를 생성하려면 UIWebView클래스를 사용한다 alloc으로 메모리를 확보하고 init메소드로 생성한다. web뷰의 주요한 프로퍼티는 다음과 같다.

BOOL scalePageToFit Web페이지의 스케일을 피트시킬까 말까

(2) 뷰 사이즈의 자동조정
=======================
UIWebVIew클래스에는 뷰 사이즈를 자동조절하는 autoresizeingMask프로퍼티가 있다. 이 프로퍼티를 지정하는 것으로 부모의 VIew의 화면 사이즈 변화에 맞춰 자신의 View의 화면 사이즈도 리사이즈하도록 된다.

(중략)

자동 스케일 조정에는 다음의 상수를 |로 연결해 지정한다.

(중략)

(3)인디케이터의 표시/비표시
==========================
현재 통신중인 것을 표시하기 위해 타이틀바에 빙글빙글 돌아가는 인디케이터를 표시한다.

(그림 생략)

UIApplication 클래스의 sharedApplication 메소드로 UIApplication 오브젝트를 취득해 networkActivityIndicatorVisivle 프로퍼트로 인디케이터의 표시/비표시를 지정한다.

(중략)

인디케이터 를 표시시키려면 다음과 같이 기술한다.
[UIApplication sharedApplication].
    networkActivityIndicatorVisible=NO;

인디케이터를 비표시하려면 다음과 같이 기술한다.
[UIApplication sharedApplication].
    networkActivityIndicatorVisible=YES;

인디케이터에는 타이틀 바에 표시하는 인디케이터 외에 뷰 상에 배치하는 컴포넌트인 인디케이터도 존재한다. 컴포넌트인 인디케이터에 대해서는 5장 [5-3 HTTP통신]에서 해설한다.

(4) WEB상의 HTML을 읽어들인다.
==============================
WEB상의 HTML을 읽어오려면 NSURL오브젝트를 생성해 그것을 인수에 NSURLRequest오브젝트를 생성해 그것을 UIWebView클래스의 loadRequest:메소드에 넘긴다. NSURL오브젝트를 생성하려면 URLWithString:메소드를 사용한다.

(중략)

NSURLRequest오브젝트를 생성하려면 NSURLReequest클래스의 requestWithURL:메소드를 사용한다.

(중략)

WEB상의 HTML을 읽어오려면 UIWebView클래스의 loadRequest:메소드를 사용한다.

(중략)

(5) WEB뷰의 델리게이트
======================
WEB 뷰의 이벤트 통지 타겟에는 UIWebViewDelegate프로토콜을 구현한 오브젝트를 지정한다. UIWebViewDelegate 프로토콜을 가진 주요 메소드는 다음과 같다.

(중략)

내비게이션 종류는 다음의 상수가 전해진다.

(중략) 링크 / 폼 송신 버튼/ 백-포워드 / 폼 송신 버튼(다시)/ 그외
표 4-6-2 내비게이션 종류 별 상수

(중략)

(6) 통신중인 경우는 다시 URL 점프 시키지 않는다.
통신중일 때 다시 링크를 클릭 또는 송신 버튼을 ㅈ누르면 통신 에러가 되어버린다. 그래서 이 프로그램에서는 링크 또는 폼 송신 버튼을 누를 때 인디케이터가 표시 되어 있으면 무시하도록 했다.

if ([UIApplication sharedApplication].
     networkActivityIndicatorVisible) return NO;

(7) 리퀘스트로부터의 URL문자열 취득
===================================
NSURLRequest 클래스의 URL메소드로 NSURL오브젝트, 거기에 NSURL클래스의 relativeStrign메소드로 HTML의 URL을 취득할 수 있다.

(중략)

(8)문자열의 전방일치검색
=======================

임의의 문자 "c"가 문자열 "str"내에 최초로 발견된 위치를 계산하는 메소드는 다음과 같이 기술한다.

-(int)indexOf:(NSString*)str c:(NSString*)c {
    NSRange range=[str rangeOfSting:c];
    if (range.location==NSNotFound) return -1;
    return range.location;
}

NSString클래스의 rangeOfString:메소드를 사용해 문자의 위치를 계산해, NSRange형의 location을 반환한다. 문자가 존재하지 않으면 lcoation에 NSNotFound가 대입되어있으므로 -1을 반환한다.

(중략)

str가 "abcdefg", c가 "b"일 때 돌아오는 값은 2가 된다. 이번에는 이것을 사용해 URL문자열의 선두가 "mailto:"인지 아닌지 "#"가 존재하는지 어떤지를 체크하고 있다.

(9)메일러 기동
=============
URIL문자열의 선두가 "mailto:"면 메일러를 기동한다. 메일러를 기동하려면 UIApplication오브젝트의 openURL:메소드에 "mailto:"로 시작하는 URL을 넘긴다. "http:"로 시작하는 URL을 지정하면 Safari가 기동한다.

(중략)

(10) 페이지 내 링크는 인디케이터를 표시하지 않는다.

페이지내 링크일 때는 통신하지않으므로 인디케이터를 표시하지 않도록 한다.

if([self indexOf:url c:@"#"]>=0) {
     return YES;
}


(11)WEB뷰는 메모리 해방전에 델리게이트 해제
WEB뷰의 메모리를 해방할 때는 delegate프로퍼티를 nil로 하고 release한다.
 통신 처리중에 델리게이트를 지정한 채 release처리를 하면 release후도 처리를 하려는 문제가 발생할 가능성이 있다.

_webView.delegate=nil;
[_webView release];


-----------------------------------

컬럼 : 리소스로부터 HTML 읽어오기

리소스로부터 HTML을 읽어오기는 다음과 같이 기술한다. 인수로는 UIWebView오브젝트와 HTML리소소스 파일명을 지정한다.

(중략)

UIWebVIew클래스의 loadHTMLString:baseURL:메소드로 HTML문자열과 베이스 URL로부터 HTML을 읽어온다.

(중략)

파일로부터 읽어오는 것은 다음 장에서 설명한다.

==============================================
컬럼 : JavaScript의 실행
WEB뷰에서 읽어들인 HTML의 JavaScript의 함수를 구현하려면 UIWebVIew클래스의 stringByEvaluatingJavaScriptFromString:메소드를 사용한다. HTML 읽어오기를 완료하지 않으면 실행할 수 없으므로 webViewDidFinishLoad:webView:메소드가 불려진 뒤 이용하라

(중략)

얼럿 표시하는 JavaScrip를 실행하면 다음과 같이 기술한다.
[_webView string ByEvaluationJavaScriptFromString:@"alert('Hello!')"];


Creative Commons License
2011/02/11 13:39 2011/02/11 13:39

텍스트 뷰 생성

from 학습/iOS 2011/02/10 13:59
(1)텍스트 뷰 생성
================
텍스트 뷰를 생성하려면 UITextView클래스를 사용하다. alloc으로 메모리르 확보하고 init메소드로 생성한다. 주요 프로퍼티는 다음과 같다.

(중략)

textAlignment프로퍼티의 택스트 배치는 다음 상수를 지정한다.

(중략)

UIViewText는 UITextField와 같이 UITextInputTraits프로토콜을 구현하고 있다. 인수에 지정한 상수는 UITextField클래스와 같다.

(중략)

(2)텍스트 뷰의 델리게이트
=========================
텍스트 뷰의 이벤트 통지 타겟에는 UITextViewDelegate 프로토콜을 구현한 오브젝트를 지정한다. UITextViewDelegate프로토콜을 가진 메소드는 다음과 같다.

=편집 관리
(중략)

=텍스트 변경
(중략)

=선택 변경
(중략)

이번에는 텍스트 변경시에 140문자제한 처리를 하고 있다. 다음과 같이 현재의 텍스트의 길이와 변경 텍스트의 길이의 합이 140을 넘는지를 체크한다.

-(BOOL)textView:(UITextView*)textView
     shouldChangeTextInRange:(NSRange)range
    replacemnetText:(NSSTring*)text{
    //최대 140문자 제한
    if (text.length>00 &&
        textView.text.length+text.length>140) {
        return NO;
    }
    return YES;
}


Creative Commons License
2011/02/10 13:59 2011/02/10 13:59

텍스트 필드

from 학습/iOS 2011/02/07 14:29
(1)텍스트 필드의 생성
===================
텍스트필드를 생성하려면 UITextField클래스를 사용한다. alloc으로 메모리를 확보후, init메소드로 생성한다. 주요 프로퍼티는 다음과 같다.
또, frame 프로퍼티와 backgroundColor프로퍼티는 UITextFiled클래스의 부모 클래스에 있는 UIView클래스에서 정의되어있다.

(중략)

textAlignment 프로퍼티는 다음과 같이 상수를 지정한다.
(중략)

borderSytle 프로퍼티의 보더 스타일에는 다음과 같이 상수를 지정한다.
(중략)

UITextField는 UITextInputTraits프로토콜을 실장하고 있다.

UITextInputTraits프로토콜 프로퍼티               의미
UIKeyboardApperance keyboardAppearance 키보드 어피어런스(표 4-3-3 참조)
UIKeyboardType keyboardType                    키보드 종류 (표 4-3-4참조)
UIkeyboardType returnKeyType                    리턴키의 종류 (표 4-3-5참조)

keyboardAppearance 프로퍼티의 키보드 어피어런스에는 다음과 같은 상수를 지정한다.

(중략)

keyboardType 프로퍼티의 키보드 종류에는 다음과 같은 상수를 지정한다.
디폴트
ASCII
숫자와 기호
URL
숫자
전화
이름
메일
알파벳
표 4-3-4 키보드 종류의 상수

returnKeyType 프로퍼티의 리턴키 종류에는 다음의 상수를 지정한다. 리턴키의 종류의 설정에 따라 변하는 것은 소프트웨어 키보드의 결정 버튼에 표시되는 문자열뿐이다. 구체적인 기능은 스스로 구현할 필요가 있다.

디폴트
Go
Google
접속
다음
루트
검색
송신
Yahoo
Done
비상 전화
표 4-3-5 리턴키 종류의 상수

(2) 텍스트 필드의 델리게이트
===========================
텍스트 필드의 이벤트 통지 타겟에는 UITextFieldDelegate 프로토콜을 구현한 오브젝트를 지정한다. UITextFieldDelegate 프로토콜을 가진 메소드는 다음과 같다.

=편집관리

(중략)

=텍스트 변경

(중략)

이번에는 리턴 버튼을 누를 때 소프트웨어 키보드를 닫는 처리와 텍스트 변경시에 140문자제한을 하는 처리를 하고 있다.


(3)소프트웨어 키보드의 표시/비표시
=================================
소프트웨어 키보드를 닫으려면 UITextField 오브젝트의 resignFirstResponder메소드를 불러 퍼스트 리스폰더를 해제한다.
컴포넌트 중에서도 가장 먼저 메소드가 보내지는 컴포넌트를 "퍼스트 리스폰더"라 부른다. 퍼스트 리스폰더는 통상 직전까지 선택된 컴포넌트다. 텍스트 입력 가능한 컴포넌트가 퍼스트 리스폰더가 되면 키보드가 열리고 해제되면 키보드가 닫힌다.

(중략)

소프트웨어 키보드를 닫으려면 becomeFirstResponder메소드를 불러 퍼스트 리스폰더를 지정한다.

(후략)


사용자 삽입 이미지

Creative Commons License
2011/02/07 14:29 2011/02/07 14:29
지난번에는 새로 OS를 설치해서 Code Sing error가 발생했는데(http://asteris.pe.kr/blog/1405), 이번에는 남의 코드를 불러왔을 때 발생하는 경우가 있었다. 내 개발환경에 등록되어있지 않은 키가 기록되어있기 때문이다.  
사용자 삽입 이미지
코드를 불러왔을 때 문제가 있다면, XCODE 왼쪽에 있는 Groups & Files 윈도우 안의 Targets를 살펴본다.
그 안에 문제가 되는 인증 정보가 들어있다.
우선 마우스 왼 버튼 클릭하여 Get Info를 선택해준다. (또는 Command+I)

사용자 삽입 이미지


새로 창이 떴으면 Build 탭을 선택하고  Code Signing 부분의 Code Signing Identity를 자신의 것으로 바꿔준다.

사용자 삽입 이미지


이제 빌드하면 잘 동작한다.

Creative Commons License
2011/02/06 09:18 2011/02/06 09:18

버튼의 생성

from 학습/iOS 2011/02/06 04:57
(1) 텍스트 버튼의 생성
=============
텍스트 표시만의 둥근사각형 버튼을 생성하려면 UIButton클래스의 buttonWithType메소드를 사용한다.

(중략)

이번에는 UIButtonTypeRoundedRect를 지정해서 둥근 사각형 버튼을 만들고, setTitle:forState:메소드로 표시하는 텍스트를 지정한다.

(중략)

프로토콜의 상태는 다음과 같은 상수를 지정한다.

컨트롤 상태의 상수               의미
UIControlStateNormal        보통 때
UIControlStateHighlighted  하이라이트 때
UIControlStateDisabled       유효하지 않은 때
UIControlStateSelected       선택시
표4-2-2 컨트롤 상태에 지정하는 상수


또, 버튼을 누른 때에 어느 버튼이 눌렸는가를 판정하기 위해서 각버튼에 태그라 불리는 ID를 지정한다. 이벤트 통지 타겟에서는 이 태그를 보고 어떤 처리를 할 것인지 결정한다.

(중략)

(2)이벤트 리스너 지정
============

컴포넌트로의 이벤트 통지 타겟의 지정은 UIControl 클래스의 addTarget:action:forControlEvents:메소드를 사용한다.  UIButton등의 이벤트 통지를 하는 컴포넌트는 UIControl을 상속하고 있다.

(중략)

SEL 은 메소드의 참조를 유지하는 형으로 "@selector(메소드명)"으로 통지 타겟의 메소드명을 지정한다. 통지 타겟의 메소드의 서식은 다음과 같다. 인수 형과 순서가 같은 메소드라면 메소드명은 자유로이 지정할 수 있다.

(중략)

여기에서는  ButtonEx 오브젝트 자신의 clickButton:메소드를 통지 타겟으로 지정한다.

action:@selector(clickButton:)

컨트롤 이벤트는 다음의 상수를 지정한다. 통상 터치 업 시에 처리를 하므로 UIControlEventTouchUpInside를 지정한다.

(중략)

(3) 이미지 버튼의 생성
=============
이미지 버튼을 성성하려면 버튼 종별에 UIButtonTypeCustom을 지정하고 표 4-2-2의 "컨트롤 상태에 지정하는 상수"에 이미지를 지정한다. 컨트롤의 상태에 지정하는 상수는 setTitle:forState:메소드와 같다.

(중략)

(4) 얼랏과 YES/NO다이얼로그 표시
얼럿을 표시하려면 UIAlertView클래스를 사용한다. alloc으로 메모리를 확보하고 intWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:메소드로 오브젝트를 생성하고 show메소드로 화면에 표시한다.

(중략)

"델리게이트"는 이벤트의 통지 타겟이다. 델리게이트에는 "권한을 위임한다"라는 의미가 있다. 얼럿과 다이얼로그에서는 버튼을 누를 때 하는 처리 등을 위임할 수 있다.

통지 타겟 오브젝트 ---- 델리게이트---->  프로토콜 구현한 오브젝트
{버튼을 누른다}    -----   통지     ----->  alertView:clickButtonAtIndex:메소드

그림 4-2-3 델리게이트에 의해 처리를 위임한다.

구체적으로 어느 정도의 처리를 위임할 것인가는 "프로토콜"이라 불리는 메소드 선언의 집합에서 정의 된다. UIAlertView의 델리게이트 프로토콜은 UIAlertViewDelegate프포토콜에서 정의 된다. 구현 순서는 다음 "(5)프로토콜의 구현"에서 해설한다.

(중략)

그밖의 버튼명의 인수의 끝에 붙어있는 "..."는 복수지정할 수 있다는 의미로 "," 단락으로 복수지정한 뒤 가장 마지막에 nil을 지정한다.

otherButtonTitiles:@"Yes", nil

이 프로그램에서는 얼럿에서는 취소 버튼명에 "OK", 그외의 버튼명과 델리게이트에 nil을 지정하고 있다. YES/NO다이얼로그에서는 취소버튼명에 "NO" 그외의 버튼에 "YES" 델리게이트에 ButtonEx 오브젝트 자신의 self를 지정하고 있다.

(5) 프로토콜 구현
==========
클래스 정의시에 다음 서식으로 프로토콜을 구현하고 있다는 것을 선언한다.

@interface 클래스명:부모클래스명 <프로토콜> {
}
@end

두개 이상의 프로토콜을 구현하는 경우 다음과 같이 ","단락으로 기술한다.

@interface 클래스명:부모클래스명 <프로토콜, 프토토콜>{
}
@end

ButtonEx클래스에서는 UIAlertDelegate 프로토콜과 UIActionSheetDelegate 프로토콜을 구현하므로 다음과 같이 기술한다.

@interface ButtonEx : UIViewController{
     UIAlertViewDelegate, UIAcitonSheetDelegate>{
}
@end

프로토콜의 메소드에는 필수 메소드의 경우에는 반드시 구현할 필요가 있다. UIAlertViewDelegate 프로토콜의 메소드는 모든 옵션 메소드이므로 이 중에 필요한 것만 구현한다.
이 프로그램에서는 alertView:didDismissWithButtonIndex:메소드를 구현했다.

(중략)

이번 얼럿 뷰의 버튼이 눌릴 때 눌린 버튼의 INDEX 를 표시하도록 했다.

(중략)

(6)액션 시트의 표시
============
액션 시트를 표시하려면 UIActionSheet 를래스를 사용한다. alloc으로 메모리를 확보 후 initWithTitle:delegate:cancelButtonTitle:destructiveButtonTitle:otherTitles:메소드로 오브젝트를 생성하고 ShowInView:메소드로 화면을 표시한다.

(중략)

(중략)

액션 시트에서도 버튼을 눌렀을 때 통지 타겟이 되는 델리게이트를 지정한다.
UIActionSheetDelegate 프로토콜의 actionSheet:didDismissWithButtonIndex 메소드를 구현한다.

(중략)

이번 액션 시트의 버튼을 눌렀을 때 눌린 버튼의 INDEX를 표시할 수 있도록 했다.


(7) #define 에 의한 문자열 치환
==================
#define은 문자열의 치환을 하는 프리프로세서 명령이다. 지정을 정의 하는 때 이용한다. 이하의 서식에서 치환전문자열과 치환후 문자열을 지정하는 것으로 빌드시 치환된다.

#define 치환전_문자열 치환후_문자열

이번에는 컴포넌트 버튼을 수치인 상태로는 알기 힘드므로, #define 에서 상수화 하고 있다.

#define BTN_ALERT  0
(후략)

Creative Commons License
2011/02/06 04:57 2011/02/06 04:57
MAC OS X(Server)를 새로 설치하고 XCODE도 새로 설치한 다음, iPHONE을 재 등록하고 device로 출력물이 나오도록 컴파일해 실행하자 다음과 같은 에러 메시지가 나타났다.

[BEROR]Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain

사용자 삽입 이미지
삽질하고 나서 안 거지만 이유는 간단했다. 개발자 등록해서 인증 받은 키가 새로 설치한 MAC OS X에 설치되어 있지 않았고, 또 키가 설치되어있더라도 그 키와 Device Provisioning Profile이 서로 연동되어있지 않았기 때문이다.

그럼 어떻게 해야하는지 설명하겠다.
과거의 인증서 등을 그대로 써도 되는진 모르겠지만, 과거의 기록이 어떤 영향을 줄지 모르므로 무조건 신규발급 받는 것을 택했다. 귀찮으면 걍 패스하고  6번으로 넘어가서 테스트해보라.


0. 유티리티/KeyChain 안의 개발자 인증서와 XCODE/ORGANIZER 안의 Provisioning Profiles를 지운다.
(OS를 새로 설치한 상태라면 없을 것이다.)

1. 개발자 홈페이지로 로그인 하고 오른쪽 메뉴의 iOS Provisioning Portal을 선택한다.
2. 왼쪽의 Certificates 메뉴를 클릭.
3. 인증서 맨 오른쪽의 Revoke를 눌러 인증서를 폐기한다.
4. 새로 인증서를 발급받는다. (다른 페이지를 보고 돌아오는 등 조금 기다리면 활성화 된다)
5. Download를 눌러 인증서를 받아 더블클릭하면 키가 추가된다.

6. iOS Provisionig Portal 의 루트페이지로 돌아가서 하단의 Launch Assistant를 클릭
7. 도움말 창이 뜬다.
사용자 삽입 이미지


사실 이대로만 따라해주면 끝난다. 아주쉽다. 여기서 시키는대로 하면 App ID를 작성하거나 기존 App ID로 Provisioning Profile을 생성해서 넣어주고, 그것을 앞에서 작업한 키와 연동시키는 과정을 수행하도록 짜여있다. 이 과정은 앱 개발자라면 누구나 할 수 있을 정도의 상식선이기 때문에 별도의 설명은 하지 않겠다.



이 과정을 거치지 않으면, 보통 Provisioning Profile이 다음과 같이 나온다. (보통 문제가 되는 상태가 이렇다)


A valid signing identity matching this profile could not be found in your keychain.
사용자 삽입 이미지

이것은 지금 쓰고있는 키와 Provisioning Profile 이 연결 되어있지 않기 때문이다.
 
KeyCahin의 key를 살펴보면 보통 요런 식으로 나와있을 것이다. (아예 Key에 아무런 값이 없을 경우도 있다. 이 때는 위의 0번 과정으로 가서 새로 등록을 하자. 물론 key명은 사용자마다 각각 다를 것이다.)
 
사용자 삽입 이미지
 
하지만, 위에서 나온 과정을 그대로 따라하면 다음과 같이 바뀌어 있음을 알 수 있다.
 
사용자 삽입 이미지
 
private key 앞에 삼각형이 달려있다. 이 부분을 클릭해보면...
 
사용자 삽입 이미지
 
다음과 같이 연결되어있음을 알 수 있다.
이제 XCODE를 실행하고 다시 컴파일해 보면 device상에서 잘 동작하는 것을 알 수 있다.
 
 


사족. 사실 맨 처음 나오는 에러에 추가 설명으로 간단히 개발자 홈에 가서 Launch Assistant를 클릭하라고만 나와주면 "대체 왜 이런 일이 생기는 걸까?" 라고 고민할 필요도 없이 간단할텐데.. 라는 생각을 해 본다.
 
사족2. 일단 위 내용은 개인 개발자 등록시 발생한 문제에 한한다. 다른 환경에선 어떻게 나오는지 해 본 적이 없어서 위와 똑같다고 장담할 수 없다. 그리고 약간의 기억에 의존하는 부분이 있어서 살짝 설명과 다를 수 있지만 크게 다르진 않을 것이다.
사족3. 남의 코드를 가져다 쓰거나 할 때 발생하는 Code Sign error 는 http://asteris.pe.kr/blog/1407 에 정리했다.

끝.
 
Creative Commons License
2011/02/05 03:00 2011/02/05 03:00
(1)문자열의 폭과 높이의 취득
==========================
레이블 영역에 대한 문자열의 위치는 가로는 좌,중앙, 우측 정렬을 지정할 수 있으나 세로는 중앙정렬만 가능하고 위 아래는 불가능하다. 따라서 문자열의 묘화와 같이 문자열의 좌상좌표에서 표시 위치를 지정하고 싶은 때는 레이블의 폭과 높이를 문자열의 폭과 높이와 같이 설정한다.
문자열의 푝과 높이를 취득하려면 NSString클래스의 sizeWithFont:메소드를 사용한다.

(중략)

(2)레이블의 생성
================
레이블을 생성하려면 UILabel 클래스를 사용한다. alloc으로 메모리를 확보하고 init메소드로 생성한다. 주요 프로퍼티는 다음과 같다.
컴포넌트의 위치와 사이즈는 frame프로퍼티에서 지정한다. frame프로퍼티는 UILabel클래스의 부모 클래스인 UIView클래스에 정의되어 있다.

(중략)

(3)컴포넌트 배치
===============
컴포넌트를 뷰에 배치하려면 UIView클래스의 addSubview: 메소드를 사용한다. 컴포넌트가 되는 클래스는 UIView클래스를 상송한다.
이번에는 UIVewControl이 가진 뷰에 레이블과 이미지뷰를 추가한다.

(중략)

(4)이미지 뷰 생성
================
이미지 뷰를 생성하려면 UIImageView 클래스를 사용한다. alloc으로 메모리를 확보하고 init메소드로 생성한다. 주요 프로퍼티는 다음과 같다.

(중략)

(5) 화면을 단말의방향에 맞춰 회전
===============================
화면을 단말의 방향에 맞춰 회전시키려면 UIViewController클래스의 shouldAutorotateToInterfaceOrientation:메소드를 오버라이트한다.

(중략)

단말의 방향은 다음과 같은 상수가 대입된다.

(중략)

단말의 방향에 맞춰 회전시키려면 [YES]를 반환한다.

(후략)

사용자 삽입 이미지

Creative Commons License
2011/01/25 17:00 2011/01/25 17:00

레이블과 이미지뷰

from 학습/iOS 2011/01/24 16:59
4-1-2 MVC 아키택쳐란?
======================
iPhone/iPad 앱은 "모델(Model)", "뷰(View)", "컨트롤러(Controller)"이렇게 3개의 구성요소로 구성되어 "MVC 아키택쳐"라 불린다. 모델은 앱에서 처리하는 데이터, 뷰는 모델의 내용을 화면에 표시하거나 유저로부터 조작을 받거나 하는 것, 컨트롤러는 모델과 뷰를 연결하는 것이다.
앱에서 처리하는 데이터는 모델에 저장된다. 컨트롤러는 그 데이터와 관련된 뷰를 찾아 표시를 경신한다. 유저가 뷰를 조작하면 그 이벤트가 컨트롤러에 통지된다. 컨트롤러는 적절한 처리를 한 뒤 모델의 데이터를 경신한다.
실제 앱을 개발할 때는 UIViewController를 상속한 클래스를 생성해, UIViewController 오브젝트가 가진 view 프로퍼티를 조작하게 된다.


     유저의 조작을 통지               데이터 경신
     ----------------->            ---------------->
뷰  <---------------- 컨트롤러 <--------------- 모델
     화면 경신                            데이터 경신을 통지
그림 4-1-2 MVC 아키택쳐

4-1-3 애플리케이션 델리게이트 편집
=================================
이번은 앱 기동시에 불리는 메소드 내에 다음에 설명하는 UIViewController클래스를 상속한 LableEx오브젝트를 생성해, LabelEx 오브젝트의 view 프로퍼티를 윈도우에 추가하는 처리를 기술한다. UIViewController 오브젝트는 인스턴스 변수로 보존된다.

리스트 4-1-1 AppDelegate_iPhone.h(iPhone용)
(중략)
리스트 4-1-2 AppDelegate_iPhone.m(iPhone용)
(중략)
리스트 4-1-3 AppDelegate_iPad.h(iPad용)
(중략)
리스트 4-1-4 AppDelegate_iPad.m(iPad용)
(중략)


4-1-4 뷰 컨트롤러에 소스 추가
============================
이번 프로그램은 2개의 소스코드 "LabelEx.h" "LabelEx.m"과 1개의 레이아웃 파일 "LabelEx.xib"로 구성되어있다. 레이아웃 파일은 Interface builder에서 편집해 이용할 수있는 것이지만, 4-7장에서는 레이아웃 파일을 다음 순서로 작성하지만, 편집은 하지 않는다. 컴포넌트의 배치는 프로그램에서 한다. InterfaceBuilder에 대한 자세한 것은 8장에서 설명한다. iPhone과 iPad에서 같은 소스코드를 사용하므로, Shared 폴더(또는 classes폴더)내에 만든다.

1) Shared폴더를 우클릭해 팝업 "추가->새 파일"을 선택해 Cocoa Touch Class의 UIViewController subclass를 선택하고 "다음"버튼을 누른다. 이때 옵션의 With XIB for user Interface를 체크해 둔다.

그림 4-1-3 뷰 컨트롤러의 소스코드 추가 1)

2) 이름에 "LabelEx.m"을 지정해 "동시에 Label.h도 작성"을 체크하고 "완료"를 누른다.

그림 4-1-4 뷰 컨트롤러의 소스코드 추가 2)

성공하면 프로젝트에 Labelex.h LabelEx.m LabelEx.xib가 추가된다.



(중략)






Creative Commons License
2011/01/24 16:59 2011/01/24 16:59

타이머

from 학습/iOS 2011/01/24 12:40
(1)타이머의 생성
================
타이머를 생성하려면 NSTimer클래스의 scheduledTimerWithTimeInterval:taget:selector:userInfo:repeats:메소드를 사용한다.

(중략)

SEL은 메소드 참조를 유지하는 형으로 "@selector(메소드명)"으로 타겟의 메소드명을 지정한다. 타겟의 메소드 서식은 다음과 같다. 인수 형과 순서가 같은 메소드라면 메소드명은 자유롭게 지정할 수 있다.

타겟 서식
-(void)timerFireMethod:(NSTimer*)theTimer
기능: 타겟에 불린다
인수: theTimer NSTimer 오브젝트

여기서는 TImerEx오브젝트 자신의 onTick:메소드를 타겟으로 지정하고 있다.

selector:@selector(onTick:)

파라메터를 건냈을 때 취득한 NSTimer 오브젝트의 userInfo 프로퍼티에서 파라메터를 취득할 수 있다.

NSTimer 클래스의 프로퍼티         의미
(id)userInfo                              rjssps vkfkapxj

NSTimer 오브젝트는 다른 오브젝트형과 달리 scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 메소도에서 생성한 시전ㅁ에 내부에서 1번 retain 되어 타이머 처리종료시에 1회 release된다. 그렇기 때문에 retain/release를 할 필요가 없다.

(2) 타이머의 정지
=================
repeats가 NO일 때는 처리 종료시에 타이머 정지가 되지만, repeats가 YES일 때는 NSTimer클래스의 invalidate메소드에서 정지하거나 애플리케이션 종료할 때까지 루프를 돈다. invalidate메소드를 부른 후는 nil을 대입하는 쪽이 안전하다.

NSTimer 클래스
-(void)invalidate
기능  : 타이머 정지


(3)타이머가 움직이는 상태로는 dealloc은 부를 수 없다
==================================================
NSTimer 오브젝트는 scheduledTimerWithTimeInterval:target:seletor:userInfo:repeats: 메소드에서 생성된 때 인수 target에서 주어진 어브젝트도 retain 한다. 그래서 타이머가 움직이고 있는 중은 target에 주어진 오브젝트의 dealloc 메소드를 부를 수 없다. dealloc 메소드내에서 invalidate메소드를 부르려면 주의하라.
타이머를 움직이고 있는 뷰를 해방할 때 우선 타이머를 invalidate메소드에서 부르고 정지시키고 뷰의 메모리를 해방시키도록 한다.
타이머가 움직이고 있을 때에 dealloc메소드가 불리지 않는 것을 확인하고 싶으면 touchesEnded:withEvent:메소드  끝에 _timer가 nil이 아닐때 UIView클래스의 removeFromSuperview메소드를 불러 보라. 콘솔에 "dealloc 메소드가 불렸다"라고 표시되질 않는다.

(중략)

타이머가 움직이지 않을 때에 dealloc메소드가 불리는 것을 확인하고 싶으면 touchesEnded:withEvent:메소드 끝에 _timer가 nil일 때 UVIew클래스의 removeFromSuperview메소드를 불러 보라. 콘솔에 "dealloc 메소드가 불렸다"라고 표시 된다.

(중략)

(4) 정기 처리
============
타이머에 의해 1초간 30회 불리는 onTick:메소드 내에서는 매 프레임 XY좌표에 XY속도를 가산한다. XY좌표가 0미만이거나 화면상이 즈이상이 될 때 XY속도를 반전 시킨다.

Creative Commons License
2011/01/24 12:40 2011/01/24 12:40

터치 이벤트의 처리

from 학습/iOS 2011/01/21 18:16
(1)터치이벤트 처리

UIResponder 클래스의 이하 4개의 터치 메소드를 오버라이드하는 것으로 터치 개시, 터치 무브, 터치 종료, 터치 캔셀 이벤트를 취득할 수 있다.
UIResponder 클래스는 UIView클래스가 상속하고있는 클래스로 이벤트 처리를 위해 인터페이스가 정의되어 있다. 다음장에서 설명할 UIViewController클래스도 UIResponder 클래스를 상속하고 있고, UIViewController 클래스에서도 터치 이벤트를 취득할 수 있도록 되어있다.

....(중략)

UITouch 오브젝트군은 터치 위치를 유지하는 UITouch오브젝트의 집합이다. NSSet클래스는 집합을 나타내는 클래스로 allObjects메소드로 NSArray형으로 변환된다.

...(중략)

touchsBegan:withEvent: 메소드로 취득한 UITouch오브젝트를 NSMutableArray형의 _touches변수에 추가하고, touchesEnded:withEvent:메소드로 취득한 UITouch오브젝트를 _touches변수로부터 소거하는 처리를 하고 있다. 이것으로 현재 터치 중 위치를 얻을 수 있다.

(2) 터치 위치의 취득
UITouch 오브젝트로부터 터치 위치를 취득하려면 locationInView:메소드를 사용한다. 터치 위치를 CGPoint치로 취득한다.

(3) 멀티 터치의 유효화
터치 이벤트를 싱글 터치만이 아니라 멀티 터치에 대응시키려면 UIView클래스의 mulitpleTouchEnabled 프로퍼티에 YES를 지정한다.

(중략)

(4) 화면의 재 묘화
화면의 재묘화를 하려면 UView클래스의 setNeedsDisplay 메소드를 부른다. setNeedsDisplay메소드를 부르면 시스템으로부터 drawRect 메소드가 불려 재묘화 처리가 행해진다.

(후략)
사용자 삽입 이미지

Creative Commons License
2011/01/21 18:16 2011/01/21 18:16
(1)그래픽컨텍스트의 취득
Quartz에서 그래픽스를 묘화하려면 그래픽스컨텍스트라 불리는 오브젝트를 취득해 그것에 대해 각종 묘화 명령을 수행합니다. 그래픽스 컨텍스트를 취득하려면 UIGraphicsGetCurrentContext함수를 이용합니다.

Quartz 함수
CGContextRef UIGraphicsGetCurrentContext()
기능: 그래픽스컨텍스트 취득
반환값: 그래픽스컨텍스트

그래픽스컨텍스트를 클래스 내의 별도 메소드로 이용하려면 인스턴스 변수에 대입합니다. 이때 C언어등에서 retain/release를 사용할 수 없습니다. 대신 CGContextRetain함수와 CGContextRelease함수를 이용합니다.

Quartz함수
CGContextRef CGContextRetain(CGContextRef c)
기능 : 그래픽스컨텍스트의 retain
인수 : c 그래픽스컨텍스트
반환값 : 그래픽스컨텍스트

Quartz함수
CGContextRef CGContextRelease(CGContextRef c)
기능 : 그래픽스컨텍스트의 release
인수 : c 그래픽스컨텍스트
반환값 : 그래픽스컨텍스트

(2)색 지정
채울 색을 지정하려면 CGContextSetRGBFillColor함수, 라인색을 지정하려면 CGContextSetRGBStrokeColor함수를 이용합니다.
Creative Commons License
2011/01/19 15:47 2011/01/19 15:47

이미지 해방

from 학습/iOS 2011/01/17 16:51
(4)이미지 해방
=============

오브젝트형 인스턴스 변수를 가진 클래스에서는 클래스 해방시에 오브젝트형의 인스턴스 변수를 모두 release합니다.
이번은 ImageEx의 뷰를 애플리케이션 종료할 때까지 해방하지 않으므로, dealloc 메소드는 부르지 않습니다. 애플리케이션 종료시에는 dealloc 메소드는 불르지않고 메모리 리크분도 포함해서 모두 메모리가 해방됩니다. 그러나, 먼 뒤 뷰의 전이를 추가한 때 메모리 해방을 잊지 않기 위해 release는 해두는 것이 좋겠지요.
뷰 해방시에 delegate 메소드가 불리는 것을 확인하는 것은 ImageEx.m에 다음과 같이 두개의 명령을 추가해 주십시오.

//묘화
- (void)drawRect:(CGRect)rect {
...중략..

[self removeFromSuperview]; //<- 추가
}

//메모리 해방
-(void)dealloc {
NSLog(@"dealloc메소드가 불렸다"); //<-추가
}

묘화시 최후에 ImageView 오브젝트를 해방하고 메모리 해방시 최초로 콘솔로의 문자열 출력을 합니다. UIView클래스의 removeFromSuperview메소드는 부모 뷰로부터 그 뷰 자신을 소거하는 명령입니다.

UIView클래스
-(void)removeFromSuperview
기능:부모 뷰로부터 뷰를 소거
Creative Commons License
2011/01/17 16:51 2011/01/17 16:51