맥북프로의 팬 속도 세밀하게 조절하기 3

이전 포스트에서 맥북프로의 팬에 윤할구리스를 발라준 이후로 더 이상 팬이 어딘가에 걸려서 나는 듯한 덜덜거리는 소리는 들리지 않습니다. 이제는 펜에서 바람 소리만 들리는데, 어지간한 작업만 해도 CPU 온도가 60도 이상 올라가서 팬이 금방 최대 속도로 돌기때문에 티비나 음악 감상 시에 너무 시끄러워서 해결 방법을 찾아봤습니다.

보통 맥에서 팬 속도 조절은 smcFanControl이 많이 소개되어 있습니다만 기본적으로 팬의 최저 속도만 정할 수 있고 애플 스크립트를 이용해서 최대 속도도 정하기도 하지만 온도에 따른 팬 속도 조절이 안되서 제 경우에는 도움이 별로 안됐습니다.
웹서핑만 해도 CPU가 45~50도 정도라서 이미 팬 속도는 3000rpm은 되고 티비보려고 EyeTV라도 실행해놓으면 59~63도정도고 티비 보면서 이것저것 작업하면 67도 이상 올라가기 때문에 조용하게 쓰려고 팬 최대 속도를 4000rpm정도로 맞춰 놓으면 시스템에 무리가 갈 정도로 온도가 올라갑니다.

이런 이유로 현재 사용 중인 유틸리티는 MacBook/Pro Extended Fan Control입니다. 아래 화면에 보이는 것처럼 팬 속도를 세밀하게 조정할 수 있도록 되어 있습니다. 이 유틸리티는 원래 Fan Control이라는 유틸리티의 기능을 확장해서 만들었다고 합니다. 제 경우에 원래의 Fan Control 유틸리티는 계속 사용하다 보면 오작동을 했었습니다.
다운로드한 다음 설치하면 [시스템 환경설정]에 [Fan Control]항목이 생겨서 위의 화면처럼 설정할 수 있습니다.
  • Lower Temp Threshold: 여기서 설정한 온도까지는 팬이 설정한 최저 속도로 돌아갑니다.
  • Upper Temp Threshold: 여기서 설정한 온도가 되면 팬이 최대 속도로 돌아갑니다.
  • Show temperatures in degrees Fahrenheit: 체크하면 온도가 화씨로 나옵니다.
  • Slowest Left Fan Speed: 왼쪽(CPU) 팬의 최저 속도를 지정합니다.
  • Slowest Right Fan Speed: 오른쪽(GPU) 팬의 최저 속도를 지정합니다.
  • Temperature sensor(s) used to control fans: 팬의 최저 속도를 따로 지정할 건지 CPU 온도에 맞출지 CPU온도에 맞출지를 정합니다.
    • CPU for both: CPU 온도가 양쪽 팬의 최저 속도의 기준이 됩니다.
    • CPU for left, GPU for right: 왼쪽 팬의 최저 속도는 CPU 온도를 기준으로 하고 오른쪽 팬의 최저 속도는 GPU온도를 기준으로 지정합니다.
    • GPU for both: GPU 온도가 양쪽 팬의 최저 속도의 기준이 됩니다.
위에 있는 화면을 설명하면 CPU온도 46도까지는 양쪽 팬이 동일하게 2000RPM으로 돌다가 73도가 되면 최대 속도(6000RPM)으로 작동하는 설정입니다.
제 경우에 EyeTV로 티비 보면서 이 포스트를 작성하는데 CPU온도는 61도고 팬 속도는 4400rpm정도 입니다.
한가지 아쉬운 점은 설정이 32비트로 되어 있어서 들어갈 때 경고창이 나오지만 작동하는데는 아무 문제 없습니다.

이글루스 가든 - 구형 맥북(프로) 생명연장 프로젝트

공유하기 버튼

 

맥북프로에 SSD 설치 후 해주어야 할 몇가지 작업들 11

맥북프로에 SSD를 설치한 다음 몇 가지 해주어야 할 일들을 정리해봤습니다.
최적화라던가 튜닝이라고 할수도 있고...그냥 HDD와는 다르니까 그에 맞게 해주면 좋을것 같은 설정입니다.

대부분의 작업은 터미널에서 직업 명령어를 쳐서 해줘야 합니다.
터미널은 [응용 프로그램]->[유틸리티] 폴더 밑에 있습니다.


SMS (Sudden Motion Sensor) 설정

애플에서는 SMS의 역할을 다음처럼 설명해 줍니다.
컴퓨터를 떨어뜨리면 Sudden Motion Sensor가 즉시 하드 드라이브 헤드를 대기시켜 충격으로 인한 하드 드라이브의 손상 가능성을 줄입니다.
SSD는 메모리칩으로 되어 있어서 읽기/쓰기 헤더나 플래터가 없기 때문에 이 기능은 필요 없습니다.
어짜피 SMS에서 오는 신호는 SSD가 무시해버리겠지만, 필요없는 기능이라면 꺼버려야죠.

SMS를 끄는 법은 애플 홈페이지에 설명되어 있습니다.
요약하면,
일단 터미널을 실행하고 다음과 같은 명령어를 쳐주면 됩니다.
$ sudo pmset -a sms 0

SMS가 꺼졌는지 확인하려면 애플 메뉴에서 [이 맥킨토시에 관하여] -> [자세한 정보] 에서 충격 감지 센서 상태가 "꺼짐"인지 확인하면 됩니다.

터미널에서 확인하려면..
$ pmset -g
...하고 sms 항목이 0으로 되어 있으면 꺼진 상태입니다.


하드디스크 잠들기 설정

[시스템 환경설정]->[에너지 절약]에 가면 “가능하다면 하드 디스크를 잠자기 상태로 둡니다.”라는 항목이 있습니다.
이 항목이 체크되어 있으면 HDD를 사용안할때 HDD 모터를 정지시켜서 전원을 절약해주는데 SSD는 모터가 없으니까 소용없는 옵션입니다.
SSD에 모터 정지하라는 신호가 가도 무시되니까 상관은 없지만 체크를 해제해놓으면 맥이 신경쓸 일이 줄어들어서 좋겠죠.


noatime 설정

파일을 읽고 쓰고 할 때마다 오에스텐은 마지막 접근 시간을 기록하는데 이 작업을 안하게 하는 설정입니다. 따라서 이 설정으로 SSD 기록 횟수를 조금 줄일 수 있습니다.
이 설정을 해주려면 다음 내용으로 com.my.noatime.plist라는 이름으로 텍스트파일을 만듭니다.

<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=“1.0”>
<dict>
        <key>Label</key>
        <string>com.my.noatime</string>
        <key>ProgramArguments</key>
        <array>
                <string>mount</string>
                <string>-vuwo</string>
                <string>noatime</string>
                <string>/</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
</dict>
</plist>

그런 다음 터미널에서 다음 명령을 실행합니다.

$ sudo chown root:wheel com.my.noatime.plist
$ sudo mv com.my.noatime.plist /Library/LaunchDaemons/

리부팅을 하고 터미널에서 mount를 했을때 다음처럼 나오면 제대로 적용된 겁니다.

/dev/disk0s2 on / (hfs, local, journaled, noatime)


sleep모드 변경 및 hibernation 파일 삭제

맥북프로의 슬립모드는 기본적으로 램의 내용을 유지하면서 디스크에도 기록해놓는 모드입니다.(세이프슬립 모드) 그래서 슬립 상태에서 배터리 전원이 다 떨어져도 슬립할 당시의 작업 내용이 안전하게 보관됩니다.
그런데 사실 맥북프로를 서브로 쓰면 이런 설정이 필요할 수도 있겠지만 메인으로 쓰는 경우에는 슬립 상태에서 배터리 전원이 다 떨어질 때까지 있는 경우가 없더군요.
게다가 램의 내용을 디스크에 그대로 저장해야 하기 때문에 전체 램 크기 만큼의 하이버네이션 파일을 유지해야하고 매번 슬립 할 때마다 전체 램 크기만큼을 매번 기록해야 하니까 SSD의 경우 용량이나 수명에 안좋아보입니다. 램이 8기가면 하이버네이션 파일도 8기가인데 SSD에서 8기가면 장난아니죠.
그러므로 슬립모드는 램 내용만 유지하는 그냥 슬립모드로 해주고 하이버네이션 파일도 삭제해줍니다.
이 작업을 하려면 터미널 상에서 다음 명령을 실행해 줍니다.

$ sudo pmset -a hibernatemode 0
$ sudo rm /var/vm/sleepimage


Spotlight 끄기

스팟라이트도 안쓰면 꺼주는게 좋습니다.
끄려면 [시스템 환경설정]->[Spotlight]에서 [개인정보]탭을 선택한 다음 [+]를 눌러서 SSD를 선택해주면 됩니다.


임시 파일들은 램디스크를 사용하도록 하기

램 용량이 충분하다면 임시 파일이 생성되는 /tmp 디렉토리가 램디스크에 마운트 되도록 해서 SSD 기록 횟수를 줄일 수 있습니다.
이 작업을 하려면 다음 내용으로 ramfs.sh라는 텍스트 파일을 만듭니다.

#!/bin/bash
ramfs_size_mb=256
mount_point=/private/tmp

ramfs_size_sectors=$((${ramfs_size_mb}*1024*1024/512))
ramdisk_dev=`hdid -nomount ram://${ramfs_size_sectors}`
newfs_hfs -v 'Volatile HD' ${ramdisk_dev}
mkdir -p ${mount_point}
mount -o noatime -t hfs ${ramdisk_dev} ${mount_point}
chown root:wheel ${mount_point}
chmod 1777 ${mount_point}

그 다음 터미널 상에서 다음 명령을 실행합니다.

$ chmod 755 ramfs.sh
$ sudo mv ramfs.sh /var/root

그리고 com.my.ramfs.plist라는 이름으로 텍스트 파일을 만듭니다.

<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=“1.0”>
<dict>
<key>Label</key>
<string>com.my.ramfs</string>
<key>ProgramArguments</key>
<array>
<string>/var/root/ramfs.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

그런 다음 터미널에서 다음 명령을 실행합니다.

$ sudo chown root:wheel com.my.ramfs.plist
$ sudo mv com.my.ramfs.plist /Library/LaunchDaemons/

램디스크 설정은 저 같은 경우 램이 3기가 밖에 안되서 안쓰고 있지만 4기가 이상 사용하는 분들은 임시 파일 디렉토리나 xcode 빌드 디렉토리 등을 램디스크로 사용하면 SSD 수명 연장에 많이 도움이 되리라 생각됩니다.

공유하기 버튼

 

SATA1 vs SATA2 맥북프로에서 속도 차이 1

웹서핑을 하다보니 최신형 맥북프로에서 OCZ VERTEX2를 설치하고 돌린 xbench 결과가 있더군요.

SATA1하고 SATA2하고 성능차이가 있는거야 당연하겠지만 수치로 보니까 엄청나네요..

그래서 한번 비교해 봤습니다.



비교 대상

 

SATA 1

SATA 2

Model

MacBookPro2,2

MacBookPro6,2

CPU

Core 2 Duo 2.33 GHz

Core i7 2.66 GHz

RAM

3072 MB

4096 MB

Bus Speed

667 MHz

1066 MHz

발표시기

2006.09

2010.04


성능차이가 좀 많이 나긴 하겠네요..



xbench 결과

단위: MB/sec

 

SATA 1

SATA 2

Sequential

Random

Sequential

Random

Write

4K

98.78

69.10

160.04

134.85

256K

104.47

105.27

148.50

158.54

Read

4K

23.22

17.91

26.97

20.89

256K

81.28

117.98

177.78

174.07


랜덤 4k 쓰기가 2배 정도 차이나네요...쩝..



점수 비교

SATA1달린 컴퓨터와 SATA2 달린 컴퓨터가 기본적으로 성능 차이도 상당하기 때문에 이런 비교가 크게 의미가 있나 싶긴 합니다만 그래도 기록 차원에서 남겨봅니다.

대충 수치상으로 1.5~2배정도 차이가 나니까..

SATA1에서는 VERTEX2가 원래 성능의 2/3정도 밖에 못낸다고 생각하면 될듯합니다.

하지만 구형 맥북프로에 SSD를 달아도 7200rpm HDD가 달린 신형보다 일반적인 작업에서는 훨씬 좋은 성능을 보여주니까 그걸로 만족해야겠습니다.


공유하기 버튼

 

구형 맥북프로에 신형 SSD 설치 결과 (OCZ VERTEX2) 14

2006년 말에 나온 맥북프로 15"에 SSD를 달아준지 두달 정도 지났습니다.

SSD를 구입하면서 걸렸던 점은 두가지인데..

맥은 아직까지 TRIM을 지원하지 않고 있고 그래서 오래쓰면 SSD가 느려진다는 점과..

SSD를 설치할 맥북프로가 SATA1만 지원해서 요즘 신형 SSD의 성능을 제대로 못낸다는 점 입니다.

그래도 결국 설치하기로 마음먹은 이유는 SSD가 달린 맥북에어를 계속 써보니 TRIM 지원 못해도 그리 느려진다는 느낌은 별로 안들고..

SATA1 전송속도만 제대로 써줘도 속도는 충분하다는 생각이 들어서죠.

설치하기로 한 SSD는 OCZ에서 나온 VERTEX2 입니다. 평가가 좋더군요.

레퍼드 리테일 패키지와 비슷한 크기로 패키징 되어있습니다.

현 상태에서 xbench 디스크 테스트 결과는 다음과 같습니다.

System Info
Xbench Version 1.3
System Version 10.6.5 (10H574)
Physical RAM 3072 MB
Model MacBookPro2,2
Drive Type OCZ-VERTEX2
Disk Test 216.46
Sequential 131.51
Uncached Write 160.89 98.78 MB/sec [4K blocks]
Uncached Write 184.64 104.47 MB/sec [256K blocks]
Uncached Read 79.36 23.22 MB/sec [4K blocks]
Uncached Read 161.73 81.28 MB/sec [256K blocks]
Random 611.48
Uncached Write 652.69 69.10 MB/sec [4K blocks]
Uncached Write 328.84 105.27 MB/sec [256K blocks]
Uncached Read 2527.79 17.91 MB/sec [4K blocks]
Uncached Read 635.82 117.98 MB/sec [256K blocks]

한달넘게 사용했고 SSD 특성 상 전체 용량이 한번 다 채워진 정도는 되는 듯해서 앞으로 계속 이 속도 정도가 나올것 같습니다.

설치한지 얼마 안된 상태의 결과는 다음과 같습니다.

System Info
Xbench Version 1.3
System Version 10.6.5 (10H574)
Physical RAM 3072 MB
Model MacBookPro2,2
Drive Type OCZ-VERTEX2
Disk Test 223.88
Sequential 135.30
Uncached Write 170.15 104.47 MB/sec [4K blocks]
Uncached Write 193.10 109.26 MB/sec [256K blocks]
Uncached Read 69.45 20.33 MB/sec [4K blocks]
Uncached Read 243.29 122.27 MB/sec [256K blocks]
Random 648.38
Uncached Write 667.05 70.62 MB/sec [4K blocks]
Uncached Write 370.16 118.50 MB/sec [256K blocks]
Uncached Read 2338.16 16.57 MB/sec [4K blocks]
Uncached Read 648.97 120.42 MB/sec [256K blocks]
 

216.46 : 223.88 로 확실히 처음 설치했을 당시가 더 빠르긴 한데 생각보다 큰 차이는 안생겼습니다.

속도 비교를 위해서 맥북프로 처음 구입시에 기본으로 달려있던 5400rpm 하드디스크의 결과를 보면...

System Info
Xbench Version 1.3 
System Version 10.5.1 (9B18) 
Physical RAM 2048 MB 
Model MacBookPro2,2 
Drive Type FUJITSU MHW2120BH 
Disk Test 37.80
Sequential 57.11
Uncached Write 67.67 41.55 MB/sec [4K blocks] 
Uncached Write 53.73 30.40 MB/sec [256K blocks] 
Uncached Read 41.79 12.23 MB/sec [4K blocks] 
Uncached Read 78.65 39.53 MB/sec [256K blocks] 
Random 28.24
Uncached Write 10.18 1.08 MB/sec [4K blocks] 
Uncached Write 63.15 20.22 MB/sec [256K blocks] 
Uncached Read 61.65 0.44 MB/sec [4K blocks] 
Uncached Read 88.36 16.40 MB/sec [256K blocks]

216.43 : 37.80 비교가 안되는군요..

기본 하드디스크에서 많이들 교체하는 7200rpm 하드디스크 테스트 결과를 봐도..

System Info
Xbench Version 1.3
System Version 10.5.5 (9F33)
Physical RAM 2048 MB
Model MacBookPro2,2
Drive Type WDC WD3200BEKT-00F3T0
Disk Test 65.24
Sequential 95.11
Uncached Write 126.57 77.71 MB/sec [4K blocks]
Uncached Write 118.65 67.13 MB/sec [256K blocks]
Uncached Read 52.73 15.43 MB/sec [4K blocks]
Uncached Read 147.90 74.33 MB/sec [256K blocks]
Random 49.65
Uncached Write 17.76 1.88 MB/sec [4K blocks]
Uncached Write 152.03 48.67 MB/sec [256K blocks]
Uncached Read 90.76 0.64 MB/sec [4K blocks]
Uncached Read 150.30 27.89 MB/sec [256K blocks]

213.43 : 65.24 확실히 기본 5400rpm 하드보다는 많이 빠르지만 비교할 대상은 아닌것 같습니다.

마지막으로 같은 회사의 구형 VERTEX SSD 테스트 결과를 보면..

System Info
Xbench Version 1.3
System Version 10.5.6 (9G55)
Physical RAM 4096 MB
Model MacBookPro2,2
Drive Type OCZ-VERTEX 1370
Disk Test 167.60
Sequential 133.29
Uncached Write 201.77 123.88 MB/sec [4K blocks]
Uncached Write 178.53 101.01 MB/sec [256K blocks]
Uncached Read 70.25 20.56 MB/sec [4K blocks]
Uncached Read 191.68 96.34 MB/sec [256K blocks]
Random 225.68
Uncached Write 87.05 9.22 MB/sec [4K blocks]
Uncached Write 259.77 83.16 MB/sec [256K blocks]
Uncached Read 2055.07 14.56 MB/sec [4K blocks]
Uncached Read 526.24 97.65 MB/sec [256K blocks]

이 결과는 오에스 설치 후에 바로 측정한 결과니까..

223.88 : 167.60으로 구형SSD보다 신형SSD가 성능이 많이 향상됐습니다.

점수만 따로 정리해보면..
점수 차이가 체감 성능으로 그대로 느껴진다고 보시면 됩니다.

결론은.....그냥 고민말고 지르세요...돈값합니다.. 무이자할부신공 ㄱㄱ~


한가지 더 덧붙이자면 열도 덜 나는듯 합니다. 7200rpm HDD 쓸 때는 팜레스트가 따뜻한 느낌이었다면 지금은 의식하지 않으면 열이 나는지 잘 못 느낄 정도입니다..

이글루스 가든 - 구형 맥북(프로) 생명연장 프로젝트

공유하기 버튼

 

맥북 프로의 팬 소음 수리하기 5

최근의 유니바디 맥북 프로는 어떤지 잘 모르겠지만 이전의 맥북프로는 고질적으로 ODD와 팬 고장 문제가 있는 것 같습니다.

ODD야 아쉬우나마 안쓰면 그만이지만 쿨링 팬 같은 경우는 한번 소리가 나기 시작하면 점점 커지기 시작하고 그러다가 완전히 멈추기라도 하면 맥북프로 사용이 불가능할 정도라서 반드시 수리를 해야합니다.

제가 가지고 있는 맥북프로(MacBook Pro 2,2 Late 2006)도 2008년 말에 왼쪽, 오른쪽 팬 2개를 모두 교체했는데 봄부터 슬슬 소음이 커지기 시작하더니 최근에는 굉음과 함께 팬 속도가 느려지는 사태까지 왔습니다.

그냥 교체할 수도 있지만 2008년 교체 당시에도 양쪽 팬 교체에 11만원 정도 들었던 기억이 나고 교체하려면 몇 일간 맥북 프로를 맡겨놔야 하기도 하고 마침 금요일 밤이라 수리를 맡길 수조차 없더군요.

결국 직접 수리 하기로 하고 뜯었습니다.


피씨 하드웨어 사이트 등에서 다른 분들 보니까 보통 팬을 분해해서 날개가 걸리는 부분을 깎아내거나 윤활제를 바르는 식이었습니다.

걸리는 부분을 깎는 방법은 분해해보면 어디가 걸리는지 알수가 없어서 실패했습니다. 여기 저기 사포로 마구 갈아봤는데 소음이 줄어드는 느낌이 없더군요. 

분해할 때는 팬 전체를 뜯어내지는 않고 전선 분리없이 윗뚜껑만 열었습니다.

암튼 그래서 윤활제를 바르기로 했는데...

보통 WD40, 자동차엔진오일, 윤활구리스, 재봉틀기름, 후시딘연고(?) 등을 쓴다고 합니다.

저는 다음 것들을 써봤습니다.
  1. WD40 - 금요일 밤에 집에서 유일하게 구할 수 있어서 써봤는데 다들 나중에 문제생긴다고 비추하는 분위기라 응급처방용으로 하루만 썼습니다. 하루만 써봐서 나중에는 어떻게 될지 모르겠지만 효과는 매우 좋았습니다.
  2. 자동차 엔진 오일 - 토요일날 자동차 엔진오일 교환하면서 콩알만큼 얻어와서 발라봤는데 WD40보다 부드럽게 작동한다는 느낌입니다. 그런데 아무래도 오일이라 그런지 삼사일 정도 사용해보니까 아주 조금씩 소음이 생기는듯 합니다. 윤활 작용은 확실한데 시간이 갈수록 증발하는 느낌.
  3. 윤활 구리스 - 결국 제대로된 윤활제를 발라야 겠다는 생각에 검색해보니 테프론 구리스라는게 젤 괜찮은듯 하더군요. 실리콘 구리스 중에 PTFE라고 써있는 제품이 테프론 구리스 인듯 합니다.

RC전문점에서 모형 자동차나 헬기 모터에 넣는 구리스 중에 젤 좋은 거 달라고 하니까 위의 제품을 주더군요.

바르는 방법은...

팬 윗 뚜껑에서 날개를 조금 힘줘서 뽑으면 사진처럼 날개만 분리되는데.. 가운데 있는 금속으로 된 중심 축에 구리스를 듬뿍 발라주면 됩니다.

저는 구리스 바르고 같이 준 오일을 그 위에 살짝 발라주고 팬 내부에도 골고루 발라줬습니다.

효과는 최고입니다. 새 팬으로 교체한 것처럼 소리도 하나도 안나고 정말 만족스럽더군요.

일주일 넘게 하루에 10시간 이상 사용했는데도 소음없이 잘 돌아갑니다.

하드디스크 교체 정도의 난이도로 숨넘어가기 직전이던 팬을 새것처럼 만들수 있다는 점에서 해볼만한 작업인듯합니다.


이글루스 가든 - 구형 맥북(프로) 생명연장 프로젝트

공유하기 버튼

 

The Core Application Design (3) 0


멀티태스킹(Multitasking)


iOS 4 이후에는, 여러개의 응용프로그램이 메모리에 존재하고 동시에 돌아갈 수 있다. 하나의 응용프로그램만 포어그라운드에서 돌아가고 다른 모든 응용프로그램들은 백그라운드에 존재한다. 이 환경에서 돌아가는 응용프로그램들은 반드시 포어그라운드와 백그라운드 사이에서 전환을 다루도록 디자인 되어야 한다.


멀티태스킹 지원을 위한 체크리스트(Checklist for Supporting Multitasking)

iOS 4 이후에서 멀티태스킹을 지원하는 응용프로그램들은 다음을 해야한다:
  • (필수) 멀티태스킹 하에서 돌아가는 동안 발생하는 상태 전환에 적절하게 반응하라. 응용프로그램들은 상태를 저장하고 포어그라운드나 백그라운드 실행에 대해 동작을 맞추기 위해 이들 전환을 감시해야 한다. 이런 전환들을 다루지 않으면 당연히 데이터 손실이나 적절하지 못한 동작을 초래할 것이다. 상태와 전환에 대한 더 많은 정보는, "응용프로그램의 상태와 전환 이해하기"를 보라.
  • (필수) 백그라운드로 이동할 때의 동작에 대한 지침을 따르라. 이들 지침은 백그라운드와 응용프로그램이 종료되야할 상황에서 응용프로그램이 올바르게 동작하도록 도와준다. 이들 지침에 대한 정보는, "믿을 수 있는, 멀티태스킹-감지 응용프로그램 되기"를 보라.
  • (권장) 응용프로그램이 필요한 시스템 변경을 보고하는 모든 통지를 등록하라. 시스템은 응용프로그램이 서스펜드된 동안 통지를 큐에 넣고 응용프로그램이 실행을 재개했을 때 배달하므로 실행으로 부드럽게 전환되도록 할 수 있다. 더 많은 정보는, "백그라운드에 있는 동안 시스템 변경에 반응하기"를 보라.
  • (선택) 백그라운드에 있는 동안 실제 작업을 하고 싶으면, 계속 돌아가기 위한 권한을 요청해야 한다. 수행할 수 있는 작업 형태에 대한 더 많은 정보는, "백그라운드에서 코드 실행하기"를 보라.
멀티태스킹을 지원하고 싶지 않다면, 응용프로그램을 끌 때 항상 종료되고 메모리에서 제거되도록 선택할 수 있다. 어떻게 이렇게 하는지에 대한 정보는, "백그라운드 실행에서 빠지기"를 보라. 


백그라운드에 있는 동안 시스템 변경에 반응하기(Responding to System Changes While in the Background)

응용프로그램이 서스펜드된 상태에 있는 동안, 관심있는 시스템-관련 이벤트들을 받지 않는다. 그러나, 대부분의 관련된 이벤트들은 시스템에 의해 수집되며 나중에 응용프로그램에 배달하기 위한 큐에 들어간다. 응용프로그램이 재개될 때 통지들로 과부하되는 것을 방지하기 위해, 시스템은 이벤트들을 합치고 응용프로그램이 서스펜드 됐을 때부터 변화에 상응하는 (각 관련된 형태의) 하나의 이벤트를 배달한다.

어떻게 응용프로그램에서 작동하는지를 이해하기 위해 한 예를 생각해보자. 응용프로그램이 서스펜드될 때 장치는 세로 방향에 있다고 가정하자. 응용프로그램이 서스펜드된 동안 응용프로그램이 다시 실행되기 전에 사용자가 장치를 왼쪽 가로방향에서 아래가 위로 그리고 마지막으로 오른쪽 가로방향으로 돌렸다. 재실행시에 응용프로그램은 장치가 오른쪽 가로 방향으로 변경됐다고 나타내는 하나의 방향 이벤트를 받는다. 물론 응용프로그램이 뷰 컨트롤러를 사용한다면, UIKit에 의해 자동으로 뷰 컨트롤러의 방향이 업데이트 된다. 응용프로그램은 추적하는 장치 방향이 확실하게 변경됐을 때만 반응해야 한다.

표 2-4는 합쳐지고 응용프로그램에 배달되는 이벤트들을 나열한다. 대부분의 경우에 이벤트들은 통지 객체의 형태로 배달된다. 그러나 어떤 이벤트들은 시스템 프레임웍에 의해 가로채지고 다른 방법으로 응용프로그램에 배달된다. 다른 언급이 없으면, 모든 이벤트들은 응용프로그램이 포어그라운드에 있는지 백그라운드에 있는지와는 상관없이 배달된다.

표 2-4 깨어있는 응용프로그램에 배달되는 통지들

Event

Notification mechanism

코드가 뷰를 지저분하다고 표시함

뷰에 있는 setNeedsDisplay나 setNeedsDisplayInRect:에 대한 모든 호출은 응용프로그램에 포어그라운드에서 재개될 때까지 합쳐지고 저장된다. 이들 이벤트는 백그라운드에서 돌고 있는 응용프로그램에는 배달되지 않는다.

악세사리가 접속되거나 끊어짐

EAAccessoryDidConnectNotification

EAAccessoryDidDisconnectNotification

장치 방향을 변경함

UIDeviceOrientationDidChangeNotification

이 통지에 추가로, 뷰 컨트롤러는 자신의 인터페이스 방향을 자동으로 갱신한다.

현저한 시간 변경이 있음

UIApplicationSignificantTimeChangeNotification

배터리 잔량이나 상태를 변경함

UIDeviceBatteryLevelDidChangeNotification

UIDeviceBatteryStateDidChangeNotification

근접 상태를 변경함

UIDeviceProximityStateDidChangeNotification

보호된 파일의 상태를 변경함

UIApplicationProtectedDataWillBecomeUnavailable

UIApplicationProtectedDataDidBecomeAvailable

외부 디스플레이가 접속되거나 끊어짐

UIScreenDidConnectNotification

UIScreenDidDisconnectNotification

디스플레이의 화면 모드가 변경됨

UIScreenModeDidChangeNotification

설정 응용프로그램에 둔 설정이 변경됨

NSUserDefaultsDidChangeNotification

현재의 언어나 로케일 설정을 변경함

NSCurrentLocaleDidChangeNotification

응용프로그램이 재개될 때 큐에 있는 모든 이벤트가 응용프로그램의 메인 런 루프를 통해 배달된다. 이들 이벤트는 바로 큐에 들어가기 때문에 일반적으로 터치 이벤트나 다른 사용자 입력 전에 배달된다. 대부분의 응용프로그램은 재개될 때 뚜렷한 지연은 일으키지 않을 만큼 빠르게 그들 이벤트를 처리할 것이다. 그러나, 응용프로그램이 깨어났을 때 사용자 입력에 반응하는게 둔하게 보인다면, Instruments를 사용하여 응용프로그램을 분석하고 핸들러 코드가 지연을 일으키는지 보는게 좋을 것이다.


우아하게 로케일 변경 다루기(Handling Locale Changes Gracefully)

사용자가 응용프로그램이 서스펜드 된 동안 장치의 언어나 로케일을 변경하면, 시스템은 NSCurrentLocaleDidChangeNotification 통지를 사용하여 그 변경을 통지한다. 이 통지를 날짜와 시간, 숫자처럼 로케일에 민감한 정보를 가진 모든 뷰를 강제로 갱신하는데 사용할 수 있다. 물론 쉽게 갱신할 수 있는 방법으로 코드를 작성하는데도 주의를 기울여야 한다:
NSLocale 객체를 가져올 때 autoupdatingCurrentLocale 클래스 메소드를 사용하라. 이 메소드는 변경에 반응하여 자신을 자동으로 갱신하는 로케일 객체를 리턴하므로 절대 재생성할 필요가 없다.
NSFormatter 객체를 캐쉬하는 것을 피하라. 날짜와 숫자 포메터는 현재 로케일 정보가 변경될 때마다 재생성되어야 한다.


응용프로그램의 설정에서 변경에 반응하기(Responding to Changes in Your Application's Settings)

응용프로그램이 "설정" 응용프로그램에 의해 관리되는 설정을 가진다면 NSUserDefaultsDidChangeNotification 통지를 감시해야한다. 사용자는 응용프로그램이 백그라운드에 있는 동안 설정을 변경할 수 있기 때문에, 이 통지를 그런 설정에서 모든 중요한 변경에 반응하는데 사용할 수 있다. 예를 들어 이메일 프로그램은 사용자의 메일 계정 정보에서 변경에 반응해야한다. 그에 대한 실패는 심각한 사생활 및 보안 문제를 야기한다. 특히 그 계정이 그 사람에게 속하지 않는데도 사용자가 여전히 예전 계정 정보를 사용하여 메일을 보낼 수 있을 것이다.

NSUserDefaultsDidChangeNotification 통지를 받으면, 응용프로그램은 모든 관련된 설정을 다시 불러오고 필요하다면 사용자  자ㅣ인터페이스를 적절하게 재 설정해야 한다. 또한 암호나 다른 보안-관련 정보가 변경된 경우에는 이전에 표시된 모든 정보를 숨기고 사용자가 새로운 암호를 입력하도록 강제해야한다.


백그라운드 실행에서 빠지기(Opting Out of Background Execution)

응용프로그램이 꺼질 때 백그라운드에 남길 원하지 않으면 응용프로그램의 Info.plist에서 UIApplicationExitsOnSuspend 키를 추가하고 그 값을 YES로 해서 백그라운드 실행 모델에서 명시적으로 빠질 수 있다. 응용프로그램이 빠졌을 때는 not running, inactive, active 상태만 순환하고 절대로 background나 suspended 상태로는 들어가지 않는다. 사용자가 응용프로그램을 끄기 위해 홈 버튼을 누렀을 때 응용프로그램 델리게이트의 applicationWillTerminate: 메소드가 호출되며 응용프로그램은 종료되고 not running 상태로 돌아가기 전에 정리하고 끝내는데 약 5초를 가진다.

백그라운드 상태에서 빠지는 것은 하지 않기를 강하게 권하지만 특정 조건 하에서는 바람직할 수도 있다. 특히 백그라운드에 대한 코딩이 응용프로그램에 상당한 복잡성을 추가하게 된다면, 응용프로그램을 종료하는 것이 더 단순한 해결책이 될 것이다. 또한 응용프로그램이 많은 양의 메모리를 소비하고 쉽게 해제할 수 없다면, 시스템은 다른 응용프로그램을 위한 공간을 만들기 위해 어쨋든 빨리 응용프로그램을 종료해야 할 것이다. 따라서, 백그라운드로 전환하는 대신에 종료되는 걸로 빠지는 것은 같은 결과를 낼 것이고 개발 시간과 노력을 절약한다.

주의: 명시적으로 백그라운드 실행에서 빠지는 것은 응용프로그램이 iOS SDK 4 이후와 링크됐을 때만 필요하다. 더 이전 버전의 SDK에 링크된 응용프로그램들은 통상적으로 백그라운드 실행을 지원하지 않으며 따라서 명시적으로 빠지는 것이 필요 없다.

응용프로그램의 Info.plist 파일에 포함할 수 있는 키들에 대한 더 많은 정보는 Information Property List Key Reference를 보라.

공유하기 버튼

 

The Core Application Design (2) 0


응용프로그램 생명 주기(The Application Life Cycle)


응용프로그램 생명 주기는 응용프로그램의 실행과 종료 사이에서 발생하는 이벤트들의 연속으로 이루어진다. iOS에서, 사용자는 홈 화면에서 아이콘을 두드려서 응용프로그램을 실행한다. 잠시 후에, 시스템은 몇 가지 전환되는 그래픽들을 표시하고 main 함수를 불러서 응용프로그램을 실행하도록 처리한다. 이 지점에서, 초기화 작업 대부분은 UIKit으로 넘어가서 응용프로그램의 사용자 인터페이스를 부르고 그 이벤트 루프를 준비한다.

그럼 2-2는 iOS 응용프로그램의 단순화된 생명 주기를 나타낸다. 이 도표는 응용프로그램이 시작하는 순간부터 꺼지는 순간까지 발생하는 일련의 이벤트들을 보여준다. 응용프로그램의 생에 있는 주요 지점에서, UIKit이 어떤 일이 일어났는지 알리기 위해 응용프로그램 델리게이트 객체에 메세지를 보낸다. 이벤트 루프 동안에, UIKit은 응용프로그램의 커스텀 이벤트 핸들러에 이벤트들을 보낸다.

그림 2-2 응용프로그램 생명 주기
iOS 4 이전에는, 한번에 하나의 응용프로그램만 돌아가도록 허용됐었다. 그 결과, 새로운 응용프로그램이 실행되기 전에, 이전의 응용프로그램은 종료됐다. 응용프로그램 생명 주기에서 응용프로그램은 항상 저장장치에서 실행됐었고 그런 다음 꺼질 때 메모리에서 제거되도록 됐었다. iOS 4 이후에서, 응용프로그램은 이제 꺼진 후에도 기본적으로 메모리에 남겨진다. 이것은 응용프로그램의 다음 실행시에 언제나 저장장치에서 응용프로그램이 시작하지는 않는다는 것을 의미한다. 또한 여러가지 서로다른 상태 전환을 다루도록 응용프로그램 코드가 디자인 되야 한다는 것을 의미한다.


Main 함수(The Main Function)

C-기반 응용프로그램처럼, 실행될 때 iOS 응용프로그램에서 주 진입 지점은 main 함수다. iOS 응용프로그램에서, main 함수는 최소로만 사용된다. 그 주된 역할은 UIKit 프레임웍으로 제어를 넘기는 것이다. 따라서, Xcode에서 생성한 어떤 새로운 프로젝트도 리스트 2-1에 보이는 것과 가은 기본 main 함수가 따라온다. 거의 예외없이, 절대 이 함수의 구현을 변경하지 말아야 한다.

리스트 2-1 iOS 응용프로그램의 main 함수
#import <UIKit/UIKit.h>
 
int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

주의: 오토릴리즈 풀은 메모리 관리에 사용된다. 코드의 기능 블럭에서 생성된 객체의 해제를 연기하는데 사용되는 Cocoa 메카니즘이다. 오토릴리즈 풀에 대한 더 많은 정보는, Memory Management Programming Guide를 보라. iOS 응용프로그램에서 오토릴리즈 풀과 관련된 특화된 메모리-관리 안내는, "현명하게 메모리를 할당하라"를 보라

main 함수의 한가운데 있는 UIApplicationMain 함수는 4개의 파라미터를 가지고 응용프로그램을 초기화 하는데 사용한다. 이 함수로 보내지는 기본 값을 절대로 변경해서는 안되지만, 응용프로그램의 시작 관점에서 그 목적을 설명할 가치는 있다.
  • argc와 argv 파라미터는 시스템에서 응용프로그램으로 보내지는 모든 실행시 인자를 가진다. 이들 인자는 UIKit 기반구조에 보내지고 다른 것은 무시된다.
  • 세번째 파라미터는 응용프로그램 수위 클래스의 이름을 식별한다. 이것은 응용프로그램이 실행되는 것을 책임지는 클래스다. nil로 지정하면 UIKit이 UIApplication 클래스를 사용하며, 권장사항이다.
  • 네번재 파라미터는 응용프로그램 델리게이트의 클래스를 식별한다. 응용프로그램 델리게이트는 시스템과 작성한 코드 사이에 고-수준 상호작용을 관리하는 책일을 가진다. nil로 지정하면 UIKit에 응용프로그램 델리게이트 객체가 응용프로그램의 메인 nib 파일에 위치한다고 알린다.
응용프로그램 객체 생성과 응용프로그램 델리게이트의 생성이나 로딩에 더해서, UIApplicationMain 함수는 응용프로그램의 메인 nib 파일도 불러온다. 모든 Xcode 프로젝트는 메인 nib 파일을 기본으로 가지며, 이 파일은 보통 응용프로그램의 윈도우와 응용프로그램 델리게이트 객체를 가진다. UIKit은 응용프로그램의 Info.plist에서 NSMainNibFile 키에 있는 값을 보고 메인 nib 파일의 이름을 얻는다. 이렇게 할 필요는 거의 없지만, 프로젝트를 빌드하기 전에 이 키의 값을 변경하는 것으로 응용프로그램에 대한 새로운 nib 파일을 지정할 수 있다. Info.plist 파일과 어떻게 응용프로그램을 설정하는데 사용하는가에 대한 더 많은 정보는, "The Information Property List"를 보라.


응용프로그램 델리게이트(The Application Delegate)

응용프로그램의 고-수준 동작을 감시하는 것은 당신이 제공하는 커스텀 객체인 응용프로그램 델리게이트 객체의 책임이다. 델리게이션은 UIApplication 객체처럼 복잡한 UIKit 객체들을 상속하는 것을 피하는데 사용되는 메카니즘이다. 상속이나 오버라이드 메소드 대신에, 수정되지 않은 복잡한 객체를 사용하고 델리게이트 객체 안에 작성한 코드를 넣는다. 관심있는 이벤트가 발생하면, 복잡한 객체가 델리게이트 객체에 메세지를 보낸다. 이들 "훅"들은 작성된 코드를 실행하고 필요한 동작을 구현하는데 사용할 수 있다.

중요: 델리게이트 디자인 패턴은 응용프로그램을 생성할 때 시간과 노력을 아끼기 위한 의도이며 따라서 이해해야 할 아주 중요한 패턴이다. iOS 응용프로그램에서 사용되는 주요 디자인 패턴의 개요는 "기반 디자인 패턴들"을 보라. 델리게이션과 다른 UIKit 디자인 패턴에 대한 더 자세한 설명은, Cocoa Fundamentals Guide를 보라.

응용프로그램 델리게이트 객체는 몇가지 중요한 시스템 메세지를 다루는 책임을 가지며 모든 iOS 응용프로그램에서 반드시 존재해야 한다. 그 객체는 UIApplicationDelegate 프로토콜을 채용한 어떤 클래스의 인스턴스도 될 수 있다. 이 프로토콜의 메소드들은 응용프로그램 생명 주기 안에 훅들을 정의하고 커스텀 동작 구현을 맘대로 할 수 있다.

UIApplicationDelegate 프로토콜의 메소드들에 대한 추가적인 정보는, UIApplicationDelegate Protocol Reference를 보라.


응용프로그램의 상태와 전환 이해하기(Understanding an Application's States and Transitions)

iOS 4와 그 이후에서 돌아가는 응용프로그램은 언제든지 여러가지 서로다른 상태 중에 하나가 될 수 있으며, 표 2-3에 나열된다. iOS 3.2와 그 이전에서 돌아가는 응용프로그램에 대해서는 백그라운드와 서스펜드 상태가 지원되지 않는다.

표 2-3 응용프로그램 상태

상태

설명

Not running

응용프로그램이 실행되지 않았거나 실행됐었지만 시스템에 의해 종료됐었다.

Inactive

응용프로그램이 포어그라운드에서 돌아가는 중이지만 현재 이벤트를 받지 못하고 있다(다른 코드가 실행되고 있을 수 있지만). 응용프로그램은 다른 상태로 전환할 때 이 상태에 일시적으로만 머문다. 어떤 기간 동안 비활성으로 머무는 것은 사용자가 화면을 잠그거나 시스템이 사용자에게 전화나 SMS 메세지가 들어오는 것 같은 어떤 이벤트에 반응하도록 알려줄 때 뿐이다. 

Active

응용프로그램이 포어그라운드에서 돌아가는 중이고 이벤트를 받고 있다.

Background

응용프로그램은 백그라운드에 있고 코드를 실행하고 있다. 대부분의 응용프로그램은 서스펜드 되는 중에 일시적으로 이 상태에 들어간다. 그러나 추가적인 실행 시간을 요구하는 응용프로그램은 일정 기간 이 상태에 머무를 수 있다. 추가적으로, 백그라운드로 직접 실행되는 응용프로그램은 비활성 상태 대신에 이 상태로 들어간다. 백그라운드에 있는 동안 어떻게 코드가 실행되는가에 대한 정보는, "백그라운드에서 코드 실행하기"를 보라.

백그라운드 상태는 iOS 4 및 그 이후에서와 멀티태스킹이 지원되는 장치에서만 이용가능하다. 이 상태가 이용가능하지 않으면, 응용프로그램은 종료되고 대신에 돌아가지 않는 상태로 이동된다.

Suspended

응용프로그램이 백그라운드에 있지만 코드는 실행되고 있지 않다. 시스템은 응용프로그램을 이 상태로 자동으로 적절한 때에 이동한다. 서스펜드된 동안, 응용프로그램은 본질적으로 현재 상태에 냉동 건조되어 있고 어떤 코드도 실행하지 않는다. 메모리-부족 상태인 동안, 시스템은 포어그라운드 응용프로그램에 더 많은 공간을 만들기 위해 통지 없이 서스펜드된 응용프로그램을 제거한다. 

서스펜드된 상태는 iOS 4 및 그 이후에서와 멀티태스킹이 지원되는 장치에서만 이용가능하다. 이 상태가 이용가능하지 않으면, 응용프로그램은 종료되고 대신에 돌아가지 않는 상태로 이동된다. 

다음 절들은 주요 상태 전환을 더 자세하게 설명하고 전환하는 동안 관찰해야 하는 일반적인 동작들을 모았다.


응용프로그램 실행하기(Launching the Application)

실행 시에, 응용프로그램은 돌고 있지 않은 상태에서 활성이나 백그라운드 상태로 이동한다. 실행되는 응용프로그램은 실행되도록 자신을 준비해야 하고 그런다음 시스템이 특정한 작업을 수행하기 위해 실행했나를 체크한다. 초기 시작 단계에서, 응용프로그램은 델리게이트의 application:didFinishLaunchingWithOption: 메소드에 이어서 applicationDidBecomeActive:나 applicatoinDidEnterBackground: 메소드(포어그라운드나 백그라운드로 전환에 따라서)를 호출한다.

주의: 백그라운드 상태에서 실행하는 것은 iOS 3.x 및 그 이전이나 멀티태스킹을 지원하지 않는 장치에서는 발생하지 않는다. 그런 상황에 있는 응용프로그램은 활성 상태로만 실행된다.

그림 2-3은 포어그라운드에서 실행될 때 일어나는 일련의 단계를 보여준다. 백그라운드에서 실행되는 순서는 applicationDidBecomeActive:메소드가 applicationDidEnterBackground: 메소드로 대체되는 것을 제외하고는 같다.

그림 2-3 활성 상태에서 실행하기
응용프로그램 델리게이트의 application:didFinishLaunchingWithOptions: 메소드는 실행 시에 대부분의 작업을 하는 책임이 있고 다음의 책임을 가진다:
  • 응용프로그램의 데이터 구조를 초기화한다.
  • 세로 방향에서 응용프로그램의 초기 윈도우와 뷰를 생성하고 부른다. 장치가 실행 시에 세로 방향이 아니라도, 초기에는 세로 방향으로 인터페이스를 생성해야 한다. application:didFinishLaunchingWithOptions: 메소드가 리턴한 후에, 응용프로그램이 윈도우에 올바른 방향으로 내용을 회전하라고 얘기한다. 그러면 그 윈도우는 보여지기 전에 회전이 일어나게 하기 위해 뷰 컨트롤러의 일반적인 방향-변경 메카니즘을 사용한다. 어떻게 인터페이스 방향 변경이 작동하는지에 대한 정보는 View Controller Programming Guide for iOS에 있는 "Custom View Controllers"에 설명된다.
  • 왜 응용프로그램이 실행됐고 적절하게 반응하는지에 대한 정보에 대해 실행 옵션 사전의 내용을 체크한다.
  • 응용프로그램을 이전 실행 상태로 복귀하기 위해 모든 저장된 설정이나 상태 정보를 사용한다.
application:didFinishLaunchingWithOptions: 메소드를 가능한 가볍게 하려고 노력해야 한다. 이 메소드에서 얼마든지 커스텀 초기화 메소드 수행할 수 있지만, 이 메소드가 작업을 완료하는데 너무 오래 걸리면, 시스템이 응응프로그램이 반응이 없다고 여기고 종료 시킬수도 있다. 그 메소드를 가볍게 만드는 한가지 방법은 작업들을 비동기적으로 초기화 하거나 모든 오래 돌아가는 작업을 두번째 스레드로 이동하는 것이다. 이것은 특히 완료하는데 불확실한 시간이 걸릴수 있는 네트웍-기반 명령에 중요하다.

application:didFinishLaunchingWithOptions: 메소드가 호출될 때, UIApplication 객체의 applicationState 속성이 응용프로그램에 적절한 상태로 미리 설정된다. 그 속성이 UIApplicationStateInactive로 설정되면, 응용프로그램은 비활성 상태에 있고 포어그라운드로 이동된다. UIApplicationStateBackground로 설정되면, 응용프로그램은 백그라운드로 이동된다. 어떤 경우든, 이 정보를 응용프로그램을 실행되기 적절하게 준비하는데 사용할 수 있다.

응용프로그램은 들어오는 백그라운드 이벤트를 다룰 필요가 있을 때만 백그라운드에서 실행된다. 백그라운드에서 실행됐을 때, 응용프로그램은 일반적으로 제한된 실행 시간을 가지며 따라서 백그라운드 이벤트 처리와 당장 관계없는 작업을 하는 것은 피해야 한다. 예를 들어, 응용프로그램의 사용자 인터페이스를 설정하는 것은 피해야 한다. 대신에, 그 인터페이스가 설정되야 하고 나중에 포어그라운드로 이동하면 그 작업을 해야한다고 기록해봐야 한다. 백그라운드 실행을 위해 어떻게 응용프로그램을 설정하나에 대한 추가적인 안내는, "Being a Responsible, Multitasking-Aware Application"을 보라.


백그라운드로 이동하기(Moving to the Background)

사용자가 홈 버튼을 누르거나 시스템이 다른 응용프로그램을 실행할 때, 포어그라운드 응용프로그램은 먼저 비활성 상태로 전환하고 그런 다음 백그라운드 상태로 전환한다. 이것은 그림 2-4에 보이듯이 응용프로그램 델리게이트의 applicationWillResignActive:와 applicationDidEnterBackground: 메소드를 호출하게 된다. 대부분의 백그라운드 응용프로그램은 applicationDidEnterBackground: 메소드에서 리턴된 후에 곧바로 서스펜드 상태로 이동한다. 응용프로그램이 더 많은 실행 시간을 요구하거나 자신이 백그라운드 실행을 지원한다고 선언하면, 이 메소드가 리턴된 후에도 계속 돌아가는 것이 허가된다.

그림 2-4 포어그라운드에서 백그라운드로 이동하기

델리게이트의 applicationDidEnterBackground:가 호출될 때, 응용프로그램은 남은 작업을 끝내고 리턴하는데 5초 정도를 가진다. 실전에서는, 가능한 빨리 이 메소드에서 리턴해야 한다. 그 메소드가 시간이 끝나기 전에 리턴을 안하면(혹은 시스템에 실행 시간을 더 요구하지 않으면), 응용프로그램은 종료되고 메모리에서 제거된다. 사용자 인터페이스를 조절하는데 관련된 어떠한 작업도 이 메소드가 끝나기 전에 수행되야 하지만 다른 작업들은 필요하다면 concurrent dispatch queue나 secondary thread로 이동시켜야 한다. 물론, 응용프로그램이 서스펜드되기 전에 코드가 실행을 끝내도록 보장하기 위한 백그라운드 실행 시간을 요구해야 할 수도 있다.

UIApplicationDidEnterBackgroundNotification 통지는 응용프로그램의 관계있는 부분에 백그라운드에 들어간다고 알리기 위해 보내질 수도 있다. 응용프로그램에서 객체들은 기본 통지 센터를 이 통지를 등록하는데 사용할 수 있다.

이후에 메모리에서 제거되는 이벤트에서 사용자 데이터와 응용프로그램을 복구하는데 필요한 어떤 상태 정보를 저장하는데 applicationDidEnterBackground: 메소드를 사용해야 한다. 응용프로그램이 백그라운드 상태로 들어갈 때, 막연히 남아있을거라는 보장은 없다. 장치의 메모리가 계속 제약된다면, 시스템은 더 많은 공간을 만들기 위해 백그라운드 응용프로그램을 제거한다. 그런 일이 일어났을 때 응용프로그램이 서스펜드 됐다면, 메모리에서 제거된다는 통지를 받지 못한다. 그러므로 사전에 모든 데이터를 저장해야 한다.

중요: 모든 멀티태스킹-지원 응용프로그램은 백그라운드로 이동할 때 확실하게 작동해야 한다. 이것은 응용프로그램이 백그라운드에 들어간 후에 바로 서스펜드될지 계속 돌아갈지에 상관없이 사실이다. 사용자의 데이터를 저장하는 것은 항상 해야하는 한 단계지만, 따라야할 다른 지침들이 있다. 이 지침들의 목록은, "Being a Responsible, Multitasking-Aware Application"을 보라.

응용프로그램이 백그라운드로 이동할 때, 모든 코어 응용프로그램 객체들은 메모리에 유지되고 사용이 가능하다. 이 객체들에는 커스텀 객체와 데이터 구조체에 더해서 응용프로그램 컨트롤러 객체와 윈도우와 뷰와 레이어가 포함된다. 그러나, 시스템은 응용프로그램을 지원하기 위해 뒤쪽에서 사용된 많은 객체들을 해제한다. 특히, 시스템은 백그라운드 응용프로그램에 대해 다음을 한다:
  • 모든 Core Animation 레이어들에 대한 backing store를 해제해서 그 레이어들의 내용이 화면 상에 나타나는 것을 막지만 현재 레이어 속성을 변경하지는 않는다. 레이어 객체 자신은 해제하지 않는다.
  • 캐쉬된 이미지들에 대한 모든 참조들을 해제한다. (응용프로그램이 이미지들을 보유하지 않는다면, 다음번에 메모리에서 제거된다.)
  • 시스템에서 관리되는 몇몇 다른 데이터 캐쉬들을 해제한다.
응용프로그램이 iOS 3.x 이전이나 멀티태스킹을 지원하지 않는 장치에서 돌아간다면, 응용프로그램은 백그라운드로 이동되는 대신에 종료된다. 어떻게 응용프로그램 종료에 반응해야 하는가에 대한 더 많은 정보는, "응용프로그램 종료에 반응하기"를 보라.


중단에 반응하기(Responding to Interruptions)

응용프로그램이 들어오는 전화나 SMS나 달력 통지에 의해 중단될 때, 응용프로그램은 일시적으로 비활성 상태로 이동한다. 이 상태를 사용자가 중단을 받아들일 건지 무시할 건지 결정할 때까지 유지한다. 사용자가 중단을 무시하면, 응용프로그램은 재활성되며, 이 때에는 비활성 상태로 이동할 때 중단했던 어떤 서비스도 재개할 수 있다. 사용자가 중단을 받아들이면, 응용프로그램은 서스펜드 상태로 이동한다. 그림 2-5는 이 처리가 되는 단계를 보여준다. 다음에 나오는 단계들은 이 처리를 더 자세하게 설명한다.

그림 2-5 응용프로그램 중단 다루기
  1. 시스템이 들어오는 전화나 SMS 메세지나 달력 이벤트 발생을 감지한다.
  2. 시스템은 응용프로그램 델리게이트의 applicationWillResignActive: 메소드를 호출한다. 또한 시스템은 응용프로그램에 터치 이벤트 배달도 중지한다. 중단은 결국 응용프로그램에 의한 제어의 임시적인 상실과 같다. 그런 제어의 손실이 응용프로그램의 동작에 영향을 미치거나 부정적인 사용자 경험을 유발한다면, 그런 일이 일어나는 것을 방지하기 위해 델리게이트 메소드에서 적절한 단계들을 가져야 한다. 예를 들어 응용프로그램이 게임이라면, 게임을 멈춰야 한다. 또한 타이머도 꺼야하고 (OpenGL을 사용한다면) OpenGL 프레임 율도 낮춰야 하며, 보통 응용프로그램을 슬립 상태에 둬야 한다. 응용프로그램이 비활성 상태인 동안, 실행은 계속 하지만 어떠한 의미있는 작업도 하지 말아야 한다.
  3. 시스템은 그 이벤트에 대한 정보와 함께 경고 패널을 표시한다. 사용자는 그 이벤트를 무시할지 반응할지 선택할 수 있다.
  4. 사용자가 그 이벤트를 무시하면, 시스템은 응용프로그램 델리게이트의 applicationDidBecomeActive: 메소드를 호출하고 응용프로그램에 터치 이벤트의 배달을 재개한다. 이 델리게이트 메소드로 타이머를 다시 켜고 OpenGL 프레임 율을 높이며 보통 응용프로그램을 슬립 상태에서 깨우는데 사용할 수 있다. 멈춰진 상태에 있는 게임에서는, 사용자가 플레이를 재개할 준비가 될 때까지 게임을 그 상태로 둘 것을 고려해야한다. 예를 들어 플레이를 재개를 조절하는 경고 패널을 표시할 수 있다.
  5. 사용자가 무시하는 대신에 그 이벤트에 반응하면, 시스템은 응용프로그램 델리게이트의 applicationDidEnterBackground: 메소드를 호출한다. 응용프로그램은 평소처럼 나중에 현재 상태로 응용프로그램을 복구하는데 필요한 어떤 사용자 데이터나 정보를 저장하고 백그라운드로 이동해야 한다. 응용프로그램이 iOS 3.x 이전이나 멀티태스킹을 지원하지 않는 장치에서 돌아가고 있으면, 응용프로그램 델리게이트의 applicationWillTerminate: 메소드를 applicationdidEnterBackground: 메소드를 호출된다.
중단에 반응하는 동안 사용자가 무엇을 하느냐에 따라서, 시스템이 그 중단이 끝날 때 응용프로그램에 리턴할 수 있다. 예를 들어 사용자가 전화를 받은 다음 끊으면, 시스템이 응용프로그램을 재실행한다. 전화 중에 사용자가 홈 화면으로 돌아오거나 다른 응용프로그램을 실행하면, 시스템은 응용프로그램에 리턴하지 않는다.

중요: 사용자가 전화를 받은 다음 통화 중에 응용프로그램으로 돌아올 때, 상태 바의 높이가 사용자가 통화 중이라는 것을 반영하여 커진다. 유사하게 사용자가 통화를 끈내면, 상태 바 높이가 보통 크기로 다시 줄어든다. 응용프로그램은 상태 바 높이에서 이런 변화들을 준비하고 적절하게 그 내용을 조절해야 한다. 뷰 컨트롤러는 자동으로 그 동작을 조절한다. 그러나 사용자 인터페이스를 프로그램적으로 배치하면, 뷰를 배치할 때 게산에 상태 바 높이를 가져와야 하고 동적 배치 변경을 위해 layoutSubviews 메소드를 구현해야 한다.

응용프로그램이 돌고 있을 때 사용자가 장치에서 Sleep/Wake 버튼을 누르면 시스템은 응용프로그램 델리게이트의 applicationWillResignActive: 메소드를 호출하고 터치 이벤트의 배달을 중지한 다음 장치를 슬립 상태에 놓는다. 나중에 사용자가 장치를 깨우면, 시스템은 응용프로그램 델리게이트의 applicationDidBecomeActive: 메소드를 호출하고 응용프로그램에 다시 이벤트 배달을 시작한다. 장치가 자는 동안, 포어그라운드 및 백그라운드 응용프로그램들은 계속 돌아가지만, 배터리 수명을 보존하기 위해 가능한 최소의 작업만 해야한다.


포어그라운드 실행 재개하기(Resuming Foreground Execution)

사용자가 현재 백그라운드에 있는 응용프로그램을 실행할 때, 시스템이 비활성 상태로 이동시킨 다음 활성 상태로 이동시킨다. 이것은 그림 2-6에 보여지듯이, 응용프로그램 델리게이트의 applicationWillEnterForeground:와 applicationDidBecomeActive: 메소드를 호출하게 된다.

그림 2-6 백그라운드에서 포어그라운드로 전환하기
포어그라운드로 이동할 때, 응용프로그램은 중지했던 모든 서비스들을 재시작해야 하고 보통 이벤트를 다시 다루기 위해 스스로를 준비한다.

주의: UIApplicationWillEnterForegroundNotification 통지는 응용프로그램이 포어그라운드에 다시 들어갈 때를 추적하는데도 이용가능하다. 응용프로그램에 있는 객체는 이 통지를 등록하는데 기본 통지 센터를 이용할 수 있다.

응용프로그램이 서스펜드된 동안, 시스템은 그 응용프로그램이 재시작할 때 영향을 줄 수 있는 이벤트를 추적하고 합친다. 응용프로그램이 올라오고 다시 실행되자마자 시스템은 그 이벤트들을 보낸다. 이 이벤트들 대부분에 대해, 응용프로그램의 기존 기반구조는 적절하게 반응해야만 한다. 예를 들어, 장치의 방향이 변경됐으면, 자동적으로 응용프로그램의 뷰 컨트롤러가 인터페이스의 방향을 적절한 방법으로 갱신해야 한다. 응용프로그램이 백그라운드에 있는 동안 시스템에 의해 추적되는 이벤트의 형식에 대한 더 많은 정보는, "백그라운드에 있는 동안 시스템 변경에 반응하기"를 보라.


응용프로그램 종료에 반응하기(Responding to Application Termination)

응용프로그램이 백그라운드로 이동되고 서스펜드되도, 다음 조건들 중에 하나가 참이면, 응용프로그램은 백그라운드로 이동되는 대신에 종료되고 메모리에서 제거된다:
  • 응용프로그램이 iOS SDK 3.x 이전에 대해 링크됐다.
  • 응용프로그램이 iOS 3.x 이전이 돌아가는 장치에서 설치됐다.
  • 현재 장치가 멀티태스킹을 지원하지 않는다; "멀티태스킹 지원이 가능한지 결정하기"를 보라.
  • 응용프로그램이 Info.plist 파일에 UIApplicationExitsOnSuspend 키를 포함한다; "백그라운드 실행 피하기"를 보라.
종료 시에 응용프로그램이 돌고있으면(포어그라운드든 백그라운드든), 시스템은 응용프로그램 델리게이트의 applicationWillTerminate: 메소드를 호출하므로, 어떠한 필요한 해제도 수행할 수 있다. 이 메소드는 다음번 실행에서 현재 상태로 응용프로그램을 복구하는데 사용할 사용자 데이터나 응용프로그램 상태 정보를 저장하는데 쓸 수 있다. 메소드 실행은 어떤 작업을 수행하고 리턴하는데 대략 5초 정도를 가진다. 시간 내에 리턴하지 않으면 응용프로그램은 강제적으로 종료되고 메모리에서 제거된다. applicationWillTerminate: 메소드는 응용프로그램이 현재 서스펜드됐다면 호출되지 않는다.

iOS 4 SDK 이후를 사용하여 응용프로그램을 개발했더라도, 여전히 응용프로그램에 대해 종료되기 위한 준비를 해야한다. 사용자는 멀티태스킹 UI를 사용하여 응용프로그램을 명확하게 종료할 수 있다. 추가적으로 메모리가 모자라게 되면, 시스템이 공간을 더 확보하기 위해 메모리에서 응용프로그램들을 제거할 것이다. 응용프로그램이 현재 서스펜드 됐다면, 시스템이 어떤 통지도 없이 메모리에서 응용프로그램을 제거한다. 그러나, 응용프로그램이 현재 백그라운드 상태에서 돌고 있으면(달리 말해 서스펜드가 아니면), 시스템이 응용프로그램 델리게이트의 applicationWillTerminate: 메소드를 호출한다. 응용프로그램은 이 메소드에서 추가적인 백그라운드 실행 시간을 요구할 수 없다.

공유하기 버튼

 

Command /usr/bin/codesign failed with exit code 1 1

계속 맥북에어에서 작업하다가 오랜만에 아이맥에서 작업하는데 다음과 같은 에러가 나더군요..


CSSM_SignData returned: 8001094A

/Users/magenta/Projects/iPhone/OBDMonitor/build/Debug-iphoneos/OBDMonitor.app: unknown error -2070=fffffffffffff7ea

Command /usr/bin/codesign failed with exit code 1


이 방법 저 방법 써보다가 맥북에어의 키체인에서 개인키를 아이맥의 키체인으로 가져와서 해결했습니다..

해결이 되서 다행이지만....에어에 있는 개인키는 원래 아이맥에서 옮긴건데...거참...

공유하기 버튼

 

The Core Application Design (1) 2

모든 iOS 응용프로그램은 UIKit 프레임웍으로 구축되며 따라서 본질적으로 같은 코어 아키텍처를 가진다. UIKit은 응용프로그램을 돌리고 사용자 입력 조작을 배열하고 화면에 내용을 표시하는데 필요한 주요 객체들을 제공한다. 응용프로그램이 다른 것과 달라지는 것은 어떻게 이들 기본 객체를 설정하는가에 따라서이고 응용프로그램의 인터페이스와 동작을 확대하기 위해 커스텀 객체들을 만들기도 한다.

여러가지 상호작용이 시스템과 실행중인 응용프로그램 사이에서 일어나고, 이들 상호작용중에 상당수가 UIKit 기반구조에 의해 자동으로 다루어 진다. 그러나, 시스템에서 들어오는 이벤트를 알아채고 싶을 때도 있다. 예를 들면, 사용자가 응용프로그램을 끌 때, 모든 관련 데이터를 날라가기 전에 저장해야 한다. 이런 상황을 위해서, UIKit은 작성한 코드에서 필요한 동작을 제공하기 위해 사용하는 훅을 제공한다.



기반 디자인 패턴들(Fundamental Design Patterns)


UIKit 프레임웍의 디자인은 Mac OS X에 있는 Cocoa 응용프로그램에서 찾을 수 있는 여러가지 디자인 패턴들로 만들어 졌다. 이들 디자인 패턴을 이해하는 것은 iOS 응용프로그램을 만드는데 중요하며, 따라서 그에 대해 배우는데 시간을 들여서 이야기할 가치가 있다. 표 2-1은 이들 디자인 패턴에 대한 간략한 개요를 제공한다.

표 2-1 iOS 응용프로그램에서 사용되는 디자인 패턴들

Design pattern

Description

Model-View-Controller

Model-View-Controller (MVC) 디자인 패턴은 독립적인 기능 영역들로 코드를 나누는 방법이다. model 부분은 응용프로그램의 하부 데이터 엔진을 정의하고 그 데이터의 무결성을 유지하는 책임을 진다. view 부분은 응용프로그램에 대한 사용자 인터페이스를 정의하고 그 인터페이스에 표시되는 데이터의 출처에 대한 정확한 정보는 가지지 않는다. controller 부분은 모델과 뷰 간에 다리로 동작하고 그 사이에서 업데이트를 돕는다.

Block objects

Block objects는 나중에 실행할 수 있는 형태로 코드와 지역 스택 변수를 캡슐화하는데 편리한 방법이다. 블럭 객체들에 대한 지원은 iOS4와 그 이후에서 이용가능하며, 주로 비동기 작업을 위한 콜스택처럼 동작하기 위해 델리게이트 대신에 사용된다.

Delegation

delegation 디자인 패턴은 상속없이 복잡한 객체를 수정하는 방법으로, 그 복잡한 객체는 그대로 사용하고 그 객체의 동작을 수정하는 모든 커스텀 코드는 델리게이트 객체로 참조되는 분리된 객체 안에 넣는다. 미리 정의한 때부터, 그 복잡한 객체는 커스텀 코드를 돌리기 위해 델리게이트의 메소드를 호출한다.

Target-action

컨트롤들은 응용프로그램에 사용자 상호작용을 알리기 위해 target-action 디자인 패턴을 사용한다. 사용자가 미리 정의된 방법(버튼 두드리는 것 같은)으로 컨트롤과 상호작용하면, 그 컨트롤은 지정한 객체(target)에 메세지(action)를 보낸다. 액션 메세지를 받으면 타겟 객체는 적절한 방법으로 반응(버튼을 누른 반응으로 응용프로그램 상태를 업데이트하는 것 같은) 할 수 있다.

Managed memory model

Objective-C 언어는 메모리에서 객체를 해제할 때를 결정하기 위해  참조-카운트 방식을 사용한다. 객체가 처음으로 생성 됐을 때, 참조 카운트가 1로 주어진다. 그런 다음에 다른 객체가 적절하게 참조 카운트를 증가시키고 감소시키는데 그 객체의 retain이나 release나 autorelease 메소드를 사용할 수 있다. 객체의 참조 카운트가 0에 도달하면, Objective-C 런타임은 객체의 클린업 루틴을 호출한 다음 할당 해제한다.

Threads and concurrent programming

모든 버전의 iOS는 명령 오브젝트 및 두번째 쓰레드의 생성을 지원한다. iOS 4와 그 이후에는, 응용프로그램이 동시적으로 작업을 실행하기 위한 하부 메카니즘으로 Grand Central Dispatch(GCD)를 사용할 수도 있다. 동시성과 구현하는데 이용가능한 기술에 대한 더 많은 정보는, Concurrency Programming Guide를 보라.

이들 디자인 패턴에 대해 더 자세한 논의는, Cocoa Fundamentals Guide를 보라.



코어 응용프로그램 객체(The Core Application Objects)


응용프로그램이 사용자에 의해 실행될 때부터 종료될 때까지, UIKit 프레임웍은 대부분의 응용프로그램의 주요 기반구조를 관리한다. iOS 응용프로그램은 시스템에서 이벤트를 연속적으로 받고 그 이벤트들에 반응해야 한다. 이벤트를 받는 것은 UIApplication 객체의 역할이지만, 그 이벤트에 대해 반응하는 것은 작성한 코드의 책임이다. 어디서 이벤트에 대한 반응이 필요한지를 이해하기 위해, iOS 응용프로그램의 전체 생명 주기와 이벤트 주기에 대해 조금 이해하는 것이 도움이 된다. 다음 절들은 이들 주기를 설명하고 iOS 응용프로그램 개발에 두루 사용되는 몇 가지 주요 디자인 패턴들에 대한 요약도 제공한다.

UIApplication 객체를 보여주는 것에 추가적으로, 그림 2-1은 iOS 응용프로그램에서 가장 일반적으로 찾을 수 있는 객체들을 보여주며, 표 2-2는 이런 형식의 객체 각각에 대한 역할을 설명한다.

그림 2-1 iOS 응용프로그램에서 주요 객체들

표 2-2 iOS 응용프로그램에서 객체들의 역할

객체

설명

UIApplicationobject

UIApplication 객체는 응용프로그램 이벤트 루프를 관리하고 응용프로그램을 위한 다른 고-수준 동작을 배치한다. 이 객체는 대부분 응용프로그램을 다양한 형태로 설정하는데 사용한다. 작성하게되는 응용프로그램-수준 코드는 이 객체와 연결되어 작동하는 응용프로그램 델리게이트 객체 안에 있다.

Application delegateobject

응용프로그램 델리게이트는 응용프로그램 실행 시에 보통 메인 nib 파일에 붙여서 제공하는 커스텀 객체다. 이 객체의 최우선 작업은 응용프로그램을 초기화 하고 화면상에 그 윈도우를 표현하는 것이다. UIApplication 객체는 응용프로그램 정지되야 할 때(들어오는 메세지 때문에)나 서스펜드 되야될 때(사용자가 홈 버튼을 눌렀기 때문에) 같은 특정한 응용프로그램-수준 이벤트가 발생했을 때 이 객체에 알려주기도 한다.

이 객체에 대한 더 많은 정보는, "응용프로그램 델리게이트"를 보라.

Data model objects

데이터 모델 객체는 응용프로그램의 내용을 저장하며 따라서 응용프로그램에 커스텀화 된다. 예를 들면, 은행 응용프로그램은 금융 거래에 대한 정보를 가질것이며, 페인팅 응용프로그램은 이미지 객체나 그 이미지의 생성하게 해주는 일련의 그리기 명령을 가질 것이다. 후자의 경우, 이미지 객체는 이미지 데이터에 대한 컨테이너일 뿐이기 때문에 여전히 데이터 객체다. 응용프로그램에서 그 이미지를 실제로 그리는 것은 여전히 다른 곳에 위치한다. 

Viewcontroller objects

뷰 컨트롤러 객체는 응용프로그램에서 화면에 의미있는 내용을 표현하는 것을 관리한다. 일반적으로, 컨텐트를 표현할 뷰를 불러오고 컨텐트의 위치를 관리하기 위한 어떤 추가적인 일반 컨트롤러를 생성하고 응용프로그램의 데이터 모델 객체와의 상호작용을 배치하는 것을 포함한다.

UIViewController 클래스는 모든 뷰 컨트롤러 객체에 대한 기본 클래스다. 뷰가 나타나는 애니메이션이나 회전을 다루는 것 같은 표준 시스템 동작에 대한 기본 기능을 제공한다. 더 특화된 뷰 컨트롤러 하위 클래스들은 시스템-특화된 화면이나 인터페이스 형식을 표시하는 것 같은 추가적인 동작을 제공한다.

어떻게 뷰 컨트롤러를 사용하는지에 대한 더 자세한 정보는, View Controller Programming Guide for iOS를 보라.

UIWindowobject

UIWindow 객체는 응용프로그램을 위한 그리기 공간을 관리한다. 대부분의 응용프로그램은 하나의 윈도우만 가진다. 응용프로그램은 뷰 컨트롤러 객체를 사용하여 새로운 뷰 집합을 나타내서 그 윈도우의 내용을 변경한다. 

뷰를 다루는 것에 더해서, 윈도우는 그들 뷰와 관리되는 뷰 컨트롤러에 이벤트를 배달하는 책임도 있다.

Viewscontrols, and layers

뷰와 컨트롤은 응용프로그램 컨텐트의 시각적 표현을 제공한다. 뷰는 지정된 사각영역 안에 어떤 컨텐트를 그리고 그 영역 안에 있는 이벤트에 반응하는 객체다. 컨트롤은 버튼과 텍스트 필드, 토글 스위치 같은 인터페이스를 구현하는 것을 책임지는 특화된 형태의 뷰다.

UIKit 프레임웍은 여러가지 서로다른 형태의 컨텐트를 표현하기 위한 표준 뷰들을 제공한다. 또한 UIView(혹은 그 자손)를 직접 상속한 커스텀 뷰를 정의할 수도 있다.

뷰와 컨트롤을 결합하는데 더해서, 응용프로그램이 뷰와 컨트롤 계속 안에 Core Animation 레이어를 결합할 수도 있다. 레이어 객체는 시각적인 컨텐트를 표현하는 실제 데이터 객체다. 뷰는 컨텐트를 그리는 장면 뒤에서 집중적으로 레이어 객체를 사용한다. 복잡한 애니메이션과 다른 형식의 세련된 시각적 효과를 구현하기 위해 인터페이스에 커스텀 레이어 객체를 추가할 수도 있다.

응용프로그램에서 객체들은 특성을 응용프로그램이 무엇으로 정의하는가에 따라 복잡한 생태계를 형성한다. 그림 2-1에서 볼 수 있듯이, 응용프로그램에서 대부분의 객체는 부분적으로나 전체적으로 커스터마이즈 가능하다. 운좋게도, 기존 UIKit 클래스들의 상단에 구축된 응용프로그램은 상당한 양의 기반구조를 무료로 받는다. 해야할 것은 필요한 커스터마이즈를 구현하기 위해 기본 동작을 오버라이드 하거나 확장할 수 있는 특정 지점을 이해하는 것이다. 이 장의 나머지는 응용프로그램의 전체적인 동작과 시스템과의 상호작용이 포함된 오버라이드 지점에 맞춰져 있다. 또한 특정 형식의 상호작용에 대해 더 찾을 수 있는 추가적인 문서도 알려준다.

공유하기 버튼

 

The Application Runtime Environment 0

iOS의 실행 환경은 프로그램의 빠르고 안전한 실행을 위해 디자인 됐다. 다음 절들은 이 실행 환경의 주요 관점을 설명하고 어떻게 응용프로그램이 그 안에서 최적으로 운영될 수 있는지에 대한 안내를 제공한다.



빠른 실행, 짧은 사용(Fast Launch, Short Use)                      


iOS 기반 장치들의 강력함은 그 즉시성에 있다. 일반적인 사용자는 주머니나 가방에서 장치를 꺼내고 다시 집어넣기 전에 몇 초 간이나 혹은 몇 분간 사용한다. 그 사용자는 그 시간 동안 전화를 받거나 연락처를 찾아보거나 현재 듣는 노래를 변경하거나 정보 몇 가지를 얻을 것이다. 응용프로그램은 실행되고 동작하는데 직관적으로 되고 빨리 실행되야 한다. 응용프로그램이 실행되는데 오래 걸린다면, 사용자는 사용하기를 꺼릴 것이다.

iOS에서, 사용자는 한번에 하나의 응용프로그램만 상호작용 한다. 따라서, 새로운 응용프로그램이 실행될 때, 이전 응용프로그램의 사용자 인터페이스는 사라진다. iOS 4 이전에, 이것은 응용프로그램 자신이 종료되고 메모리에서 제거된다는 것을 의미했다. 그러나, iOS 4와 이후에는, 종료한 응용프로그램은 백그라운드로 이동한다. 응용프로그램은 다시 실행되거나 시스템이 사용 중인 메모리를 반환하도록 할 때까지 백그라운드에 유지된다. 

백그라운드에서 돌아가기 위한 능력은 응용프로그램 재실행이 매우 빨라진다는 것을 의미한다. 백그라운드로 이동할 때, 응용프로그램의 객체들은 메모리에 유지되며 대부분의 경우에 응용프로그램 자신은 서스펜드 상태로 들어간다. 사용자가 응용프로그램을 재실행하면, 사용자 인터페이스를 재적재하고 이전 상태로 복구하는 것 없이 정확한 지점으로 간단하게 돌아온다.

응용프로그램이 백그라운드에서 돌아갈 수 있음에도 불구하고, 그렇게 계속 된다고 보장되지는 않는다. 메모리가 부족해지면, 시스템은 최근에 실행되지 않은 응용프로그램들을 제거한다. 이 일이 언제든, 그리고 어떨때는 아무 통보없이 일어날 수 있기 때문에, 응용프로그램은 여전히 백그라운드로 이동할 때 모든 저장안된 데이터 외에도 현재 상태에 대한 정보를 저장해야 한다. 언젠가 재실행되야 한다면, 이 정보를 이전 상태로 복귀해서 항상 실행됐던 것처럼 보이는데 사용할 수 있다. 그렇게 하는 것이 사용자가 응용프로그램을 마지막 사용했을 때로 바로 돌아가도록 해서 더 일관된 사용자 경험을 제공한다.



특화된 시스템 동작들(Specialized System Behaviors)              


대부분에서, iOS는 Mac OS X와 같은 방법으로 같은 기능과 동작을 한다. 그러나, iOS의 동작이 Mac OS X와 다른 곳이 있다.


가상 메모리 시스템(The Virtual Memory System)

프로그램 메모리를 관리하기 위해서, IOS는 Mac OS X과 본질적으로 같은 가상 메모리 시스템을 사용한다. iOS에서, 각 프로그램은 여전히 그 자신의 가상 주소 공간을 갖지만, (Mac OS X와 다르게) 사용할 수 있는 가상 메모리는 이용 가능한 물리 메모리의 양에 의해 제약 된다. 이 이유는 메모리가 꽉 찼을 때, iOS가 휘발성 페이지들을 디스크에 쓰지 않기 때문이다. 대신에, 실행 중인 응용프로그램이 필요한 공간을 가질수 있게 하기 위해, 가상 메모리 시스템은 필요한대로 휘발성 메모리를 풀어준다. 이런 작업은 사용되지 않으며 코드 페이지처럼 읽기 전용 컨텐츠를 가진 메모리 페이지를 제어하는 것으로 한다. 그런 페이지들은 다시 필요해지면 이후에도 항상 메모리에 다시 불려질 수 있다. 

메모리가 계속 제약 받는다면, 시스템은 실행 중인 응용프로그램에 추가적인 메모리를 해제하라고 요청하는 통지를 보낼 수도 있다. 모든 응용프로그램들은 이 통지에 응답해야하고 메모리 압박을 푸는데 협조하기 위해 자신의 역할을 해야한다. 어떻게 응용프로그램에서 그런 통지들을 다루는지에 대한 정보에 대해, "메모리-부족 경고 관찰하기"를 보라.


자동 슬립 타이머(The Automatic Sleep Timer)

iOS가 전력을 절약하기 위해 하는 한 방법은 자동 슬립 타이머를 통한 것이다. 시스템이 장기간 터치 이벤트를 감지하지 못하면, 초기에는 화면을 어둡게 하고 결국에는 완전히 꺼버린다. 대부분의 개발자들이 이 타이머를 그냥 두지만, 응용프로그램이 터치 입력을 사용하지 않는 게임 개발자들은 응용프로그램이 돌아가는 동안 화면이 어두워지는 것을 방지하기 위해 이 타이머를 끌 수 있다. 타이머를 끄기 위해, 공유되는 UIApplication 객체의 idleTimerDisabled 속성을 YES로 설정한다.

이 동작은 엄청나게 전력을 소비하기 때문에, 슬립 타이머를 끄는 것은 무슨 짓을 해서라도 피해야 한다. 사용을 고려해야 하는 응용프로그램은 지도 응용프로그램이나 게임이나 터치 입력에 의존하지 않지만 장치의 화면에 시각적 내용을 표시해야하는 응용프로그램 뿐이다. 오디오 응용프로그램은 오디오 컨텐트는 화면이 어두워져도 계속 플레이 할 수 있기 때문에 타이머를 끌 필요 없다. 타이머를 끈다면, 시스템이 더 많은 전력을 보존하도록 가능한 빨리 다시 켜야 한다. 어떻게 응용프로그램에서 전력을 절약하는지에 대한 추가적인 팁에 대해서, "전력 소비 줄이기"를 보라.


멀티태스킹 지원(Multitasking Support)

iOS 4와 그 이후에서, 응용프로그램은 백그라운드에서 돌아가는 동안 작업을 수행할 수 있다. 사용자가 응용프로그램을 나가면, 그 프로세스가 종료되는 대신에, 응용프로그램이 백그라운드로 이동된다. 백그라운드로 이동되자마자, 대부분의 응용프로그램은 서스펜드되서 돌아가지 않고 추가적인 전력을 소비하지 않는다. 그러나, 계속 돌아가야 하는 응용프로그램은 시스템에 돌아가야하는 실행 시간을 요청할 수 있다.

응용프로그램이 백그라운드에서 도는지 서스펜드 됐는지와 상관없이, 응용프로그램이 계속 메모리에 있다는 사실은 응용프로그램 재실행이 아주 적은 시간에 된다는 것을 의미한다. 응용프로그램의 객체(윈도우와 뷰를 포함한)는 보통 메모리에 유지되며 따라서 응용프로그램에 이후에 사용자에 의해 재실행될 때 재생성될 필요가 없다. 그러나, 메모리가 모자라지면, 시스템은 포어그라운드 응용프로그램에 더 많은 공간을 주기 위해 백그라운드 응용프로그램을 제거할 수 있다. 응용프로그램이 계속 백그라운드에 있었던 것처럼 나타나게 하기 위해, 응용프로그램은 백그라운드로 이동할 때 현재 상태에 대한 정보를 저장해야 하고 이후에 재실행에서 그 상태로 자신을 복귀할 수 있어야 한다.

멀티태스킹에 대한 개요와 무엇을 지원해야 하는지에 대해, "멀티태스킹"을 보라.



보안(Security)                                                                          


iOS의 중요한 작업은 사용자의 장치와 그 위에서 돌아가는 응용프로그램의 보안을 보장하는 것이다. 그러기 위해서, iOS는 사용자 데이터의 무결성을 보장하고 응용프로그램이 다른 응용프로그램이나 시스템을 침범하지 않는다는 것을 보장하기 위해 몇 가지 기능을 수행한다. 


응용프로그램 샌드박스(The Application Sandbox)

보안상의 이유로, iOS는 파일 시스템에서 하나의 장소에 응용프로그램(설정과 데이터를 포함하여)을 제약한다. 이 제약은 응용프로그램의 "샌드박스"로 알려진 보안 기능의 부분이다. 샌드박스는 파일과 설정, 네트웍 자원, 하드웨어 등등에 대한 응용프로그램의 접근을 한정하는 세밀한 제어의 집합이다. iOS에서, 응용프로그램과 그 데이터는 다른 응용프로그램이 접근 할 수 없는 보안 위치에 들어있다. 응용프로그램이 인스톨되면, 시스템은 응용프로그램에 대해 유일하고 불투명한 식별자를 산출한다. 루트 응용프로그램 디렉토리와 이 식별자를 사용하여, 시스템은 응용프로그램의 홈 디렉토리에 대한 경로를 구성한다. 따라서 응용프로그램의 홈 디렉토리는 다음의 구조를 갖도록 표현된다:

/ApplicationRoot/ApplicationID/

인스톨 과정 동안에, 시스템은 응용프로그램의 홈 디렉토리과 몇개의 주요 하위디렉토리를 생성하고, 응용프로그램 샌드박스를 설정하고, 홈디렉토리에 응용프로그램 번들을 복사한다. 각 응용프로그램과 그 데이터에 대해 하나의 장소를 사용하는 것은 백업과 복구 작업과 응용프로그램 업데이트와 언인스톨을 단순하게 한다. 각 응용프로그램에 대해 생성된 응용프로그램-특화 디렉토리에 대한 더 많은 정보는, "몇 가지 중요한 응용프로그램 디렉토리들"을 보라. 응용프로그램 업데이트와 백업과 복구 작업에 대한 정보는, "백업과 복구"를 보라.

중요: 샌드박스는 공격자가 다른 응용프로그램과 시스템에 발생시킬수 있는 손해를 한정하지만, 일어나는 공격을 막을 수는 없다. 달리 말하면, 샌드박스는 악의적인 존재에 의한 직접 공격에서 응용프로그램을 보호하지 않는다. 예를 들면, 입력 처리 코드에 이용가능한 버퍼 오버플로우가 있고 사용자 입력을 검사하는데 실패했다면, 공격자가 프로그램을 충돌하도록 할 수 있고 공격자의 코드를 실행하는데 사용할 수도 있다.


파일 보호(File Protection)

iOS 4와 그 이후에, 응용프로그램은 사용자의 장치가 잠겼을 때 파일을 암호화하고 접근할 수 없게 하는 파일 보호를 사용할 수 있다. 파일 보호는 민감한 데이터로 작업하는 응용프로그램에 대한 보안 단계를 추가하기 위한 특정 장치(iPhone 3GS 같은)에서의 내장형 암호화 하드웨어의 이점을 가진다. 보호된 파일들은 디스크에 항상 암호화된 형식으로 저장된다. 사용자의 장치가 잠겨진 동안에는, 데이터를 소유한 응용프로그램조차도 암호화된 파일에 있는 데이터에 접근할 수 없다. 사용자는 파일에서 해독된 데이터를 응용프로그램이 가져오도록 하기 전에 장치를 완전히 잠금해제해야(적절한 암호 입력으로) 한다. 

장치에서 파일을 보호하는 것은 몇 가지 단계를 요구한다:
  • 사용자의 장치에서 파일 시스템은 파일 보호를 지원하도록 포멧되어야 한다. 기존 장치에서는, 사용자가 장치를 다시 포멧하고 백업으로 모든 내용을 복구해야 한다.
  • 사용자의 장치는 패스코드 잠금 설정이 켜져야 하고 유효한 패스코드를 설정해야 한다.
  • 응용프로그램은 보호되어야 할 데이터 파일을 지정하고 적절한 메타데이터 속성을 넣어야 한다; "보호되는 파일 만들기"를 보라.
  • 응용프로그램은 파일이 잠궈지는 상황에 적절하게 반응해야 한다; "보호된 파일의 이용 가능 여부 결정하기"를 보라.
어떤 파일을 응용프로그램이 보호되는 걸로 구분할지를 결정하는 것은 당신에게 달려있다. 응용프로그램은 파일 별로 파일 보호를 켜야하고, 한번 켜진 보호는 제거될 수 없다. 또한, 응용프로그램은 데이터 파일들이 보호되어야 하지만 현재는 안되는 상황을 준비해야 한다. 이런 상황은 파일 보호가 아직 추가되지 않았던 이전 백업에서 장치를 복구 했다면 발생될 수 있다.

응용프로그램에서 파일 보호 지원 구현에 대한 더 많은 정보에 대해서는, "보호된 파일로 작업하기"를 보라.


키체인 데이터(Keychain Data)

키체인은 암호와 그외의 기밀을 위한 안전하고, 암호화된 컨테이너다. 응용프로그램에 대한 키체인 데이터는 응용프로그램 샌드박스 바깥에 저장된다. 응용프로그램이 언인스톨되면, 그 데이터는 자동으로 제거된다. 사용자가 iTunes를 사용하여 응용프로그램 데이터를 백업할 때, 키체인 데이터도 또한 백업된다. 그러나, 백업이 만들어졌던 곳에서 장치로 단지 복원될 뿐이다. 응용프로그램의 업그래이드는 키체인 데이터에 영향을 주지 않는다.

iOS 키페인에 대한 더 많은 것은 키체인 서비스 프로그래밍 가이드에 있는 "키체인 서비스 개념"을 보라.



파일 시스템(The File System)                                        


응용프로그램과 생성한 모든 파일들은 플래쉬-기반 메모리에 있는 사용자의 미디어 및 개인용 파일들과 공간을 공유한다. 응용프로그램은 다른 파일 시스템처럼 작동하고 표준 시스템 루틴을 사용하여 접근되는 로컬 파일 시스템을 사용하여 파일에 접근할 수 있다. 다음의 절들은 로컬 파일 시스템에 접근할 때 주의해야하는 몇 가지 것들을 설명한다.


몇 가지 중요한 응용프로그램 디렉토리들

보안 목적을 위해, 응용프로그램은 그 데이터와 설정을 기록할 수 있는 몇 개의 위치만 가진다. 응용프로그램이 장치에 인스톨될 때, 홈 디렉토리가 그 응용프로그램에 대해 생성된다. 표 1-1은 접근해야 될 수 있는 홈 디렉토리 안에 있는 몇 가지 중요한 하위디렉토리를 나열한다. 이 표는 각 디렉토리에 대한 정해진 용도와 접근 제한을 설명하고 디렉토리의 내용이 아이튠즈에 의해 백업될지를 가리쳐준다. 응용프로그램 홈 디렉토리에 대한 더 많은 정보에 대해서는, "응용프로그램 샌드박스"를 보라.


표 1-1 iOS 응용프로그램의 디렉토리

디렉토리

설명

<Application_Home>/AppName.app

응용프로그램 자신이 들어있는 번들 디렉토리다. 응용프로그램은 사인되었어야 하기 때문에, 실행시에 이 디렉토리의 내용을 변경하면 안된다. 그렇게 하면 나중에 실행에서는 응용프로그램이 막힐 것이다.

iOS 2.1과 그 이후에는, 이 디렉토리의 내용은 아이튠즈에서 백업되지 않는다. 그러나 아이튠즈는 앱스토어에서 구매된 모든 응용프로그램의 처음 동기화를 수행한다.

<Application_Home>/Documents/

이 디렉토리는 사용자 문서와 응용프로그램 데이터 파일을 저장하는데 사용한다. 이 디렉토리의 내용은 파일 공유를 통해서 사용자에게 이용가능해질 수 있다. 

이 디렉토리의 내용은 아이튠즈에서 백업된다.

<Application_Home>/Library/

이 디렉토리는 응용프로그램-특화 파일들의 최상위 디렉토리다. 보통 표준 하위디렉토리 중에 하나에 파일들을 넣지만 커스텀 하위디렉토리도 생성할 수 있다(어떻게 표준 하위디렉토리에 대한 참조를 얻는가는, "응용프로그램 디렉토리에 대한 경로 얻기"를 보라). 사용자 데이터 파일에 대해 이 디렉토리를 사용하면 안된다.

이 디렉토리의 내용은 아이튠즈에서 백업된다.

<Application_Home>/Library/Preferences

이 디렉토리는 응용프로그램-특화된 설정 파일들을 가진다. 설정 파일들을 직접 생성하면 안되지만 대신에 응용프로그램 설정을 얻고 넣기 위해 NSUserDefaults 클래스나 CFPreferences API를 사용한다.

이 디렉토리의 내용은 아이튠즈에서 백업된다.

<Application_Home>/Library/Caches

응용프로그램의 실행 사이에나 응용프로그램 업데이트 동안에 유지하고 싶은 모든 응용프로그램-특화된 지원 파일들을 작성하기 위해 이 디렉토리를 사용한다. 응용프로그램은 보통 이 파일들을 추가하고 삭제할 책임이 있다. 또한 아이튠즈는 장치의 완전 복구 동안에 이 파일들을 제거하기 때문에 필요하면 재생성할 수도 있어야 한다. 

iOS 2.2와 그 이후에, 이 디렉토리의 내용은 아이튠즈에서 백업되지 않는다.

<Application_Home>/tmp/

응용프로그램의 실행 사이에 유지하지 않아도 될 임시 파일들을 기록하는데 이 디렉토리를 사용한다. 응용프로그램은 더이상 필요하지 않을 때 이 디렉토리에서 파일들을 제거해야 한다(시스템은 또한 응용프로그램이 돌아가지 않을 때 이 디렉토리에서 남아있는 파일들을 제거한다).

iOS 2.1과 그 이후에, 이 디렉토리의 내용은 아이튠즈에서 백업되지 않는다.

어떻게 특정한 디렉토리의 경로를 얻나에 대한 정보는, "응용프로그램 디렉토리에 대한 경로 얻기"를 보라. 어떤 응용프로그램 디렉토리가 백업되는 가에 대한 자세한 정보는, "무엇이 백업되나?"를 보라.



대소문자 구분 파일 시스템(A Case-Sensitive File System)

iOS-기반 장치를 위한 파일 시스템은 대소문자 구분이다. 파일명으로 작업할 때마다, 대소문자 구분을 정확하게 하지 않으면 파일을 열수 없거나 접근할 수 없을 것이다.


사용자의 데스크탑 컴퓨터와 파일 공유하기

사용자 데이터 파일에 접근하고 싶어하는 응용프로그램은 응용프로그램 파일 공유를 사용하여 그렇게 할 수 있다. 파일 공유는 응용프로그램과 사용자의 데스크탑 컴퓨터 간에만 파일의 공유를 가능하게 해준다. 응용프로그램이 같은 장치에 있는 다른 응용프로그램과의 파일을 공유하는 것은 허가되지 않는다. 응용프로그램 간에 데이터와 파일을 공유하기 위해, 클립보드나 문서 상호작용 컨트롤러 객체를 사용한다.

어떻게 응용프로그램에서 파일 공유를 지원하는가에 대한 정보는, "사용자와 파일 공유하기"를 보라.



백업과 복구(Backup and Restore)                                      


iTunes 응용프로그램은 적절한 상황에 자동으로 사용자 데이터의 백업과 복구를 처리한다. 그러나, 응용프로그램은 경우에 따라 파일들이 백업되고 복구되는 것을 보장하기 위해 파일들을 어디에 넣어야 하는지 알아야 한다.


무엇이 백업되나?(What Is Backed Up?)

백업과 복구 작업에 대한 어떤 방법으로도 응용프로그램을 준비할 필요는 없다. iOS 2.2과 그 이후에서, 장치가 컴퓨터에 연결되고 동기화될 때, iTunes는 다음 디렉토리에 있는 것들을 제외하고는, 모든 파일의 증분 백업을 수행한다:

  • <Application_Home>/AppName.app
  • <Application_Home>/Library/Caches
  • <Application_Home>/tmp

iTunes는 응용프로그램 번들 그 자신을 백업하지만, 모든 동기화 작업 때마다 하는 것은 아니다. 장치 상에서 App Store로부터 구매한 응용프로그램은 장치가 다음번에 아이튠즈와 싱크될 때 백업된다. 응용프로그램은 자신이 변경(예를 들면, 응용프로그램이 업데이트 됐다던지)되지 않는다면 그 다음 싱크 작업에는 백업되지 않는다. 

장시간 걸리는 동기화 작업을 방지하기 위해서, 응용프로그램의 홈 디렉토리 안에 어디에 파일들을 넣을지를 선택해야 한다. <Application_Home>/Documents 디렉토리는 사용자 문서와 응용프로그램 데이터 파일을 저장하는데 사용되야 한다. 임시 데이터를 저장하는데 사용되는 파일들은 Application Home/tmp 디렉토리 안에 위치해야 하고 더이상 필요없을 때 응용프로그램에 의해 삭제되어야 한다. 응용프로그램이 이후의 실행에서 사용될 수 있지만 백업될 필요는 없는 데이터 파일을 생성한다면, 그런 파일들은 Application Home/Library/Caches 디렉토리에 위치해야 한다.

주의: 응용프로그램이 커다란 데이터 파일이나 자주 변경되는 파일을 생성한다면, <Application_Home>/Documents 디렉토리가 아니라 Application Home/Library/Caches 디렉토리에 저장할 것을 고려해야 한다. 커다란 데이터 파일을 백업하는 것은 백업 과정을 현저하게 느려지게 할 수 있다. 정기적으로 변경(따라서 자주 백업되야하는)되는 파일에 대해서도 마찬가지다. 이들 파일을 Caches 디렉토리에 위치시키면 매번 동기화 작업마다 백업(iOS 2.2와 그 이후에서)되는 것이 방지된다.

응용프로그램에서 어떻게 디렉토리를 사용해야 하는지에 대한 추가적인 안내는, 표 1-1을 보라.


응용프로그램 업데이트 중에 저장되는 파일들(Files Saved During Application Updates)

사용자가 응용프로그램 업데이트를 다운로드할 때, 아이튠즈는 새로운 응용프로그램 디렉토리에 업데이트를 설치한다. 그런 다음 예전 설치를 삭제하기 전에 새로운 응용프로그램 디렉토리에 예전 설치에서 사용자의 데이터 파일을 이동한다. 다음 디렉토리에 있는 파일은 업데이트 과정 중에 보관된다는 것이 보장된다:
  • <Application_Home>/Documents
  • <Application_Home>/Library
다른 사용자 디렉토리에 있는 파일도 이동될 수 있지만, 업데이트 후에 그 존재가 있는지 의존하면 안된다.



시뮬레이터(The Simulator)                                                


iPhone Simulator는 앱스토어에 배포하기 전에 응용프로그램을 테스트 하는데 사용하는 도구다. 시뮬레이터는 실제 장치에 있는 것에 가깝지만 동일하지는 않은 실행 환경을 제공한다. 디스크 페이징 지원에서 지연과 같은 장치에서 일어날 수 있는 많은 제약이 시뮬레이터에는 존재하지 않는다. 또한, OpenGL ES 같은 몇몇 기술들은 장치에서 할 때와 시뮬레이터에서 같은 방식으로 작동하지 않을 것이다.

시뮬레이터와 그 기능에 대한 더 많은 정보는, iOS Development Guide에 있는 "Using iPhone Simulator"를 보라.



이용 가능한 하드웨어 지원 결정하기                                     


iOS를 위해 디자인된 응용프로그램은 서로다른 하드웨어 기능을 가진 장치에서 실행될 수 있다. 가속도계나 Wi-Fi 네트워킹 같은 기능은 모든 장치에서 이용가능하지만, 몇몇 장치는 카메라나 GPS 하드웨어를 가지고 있지 않을 수 있다. 응용프로그램이 그런 기능을 요구한다면, 그 응용프로그램을 구매하기 전에 사용자에게 항상 그 사실을 알려야 한다. 필수적이지는 않지만, 현재 지원하는 기능에 대해서는, 그 기능을 사용하기 전에 이용가능한지 체크해야 한다.

중요: 어떤 기능이 응용프로그램을 돌리기 위해서 반드시 제공되야 한다면, 응용프로그램의 Info.plist 파일에 UIRequiredDeviceCapabilities 키를 적절하게 설정한다. 이 키는 사용자가 장치에서 제공되지 않는 기능을 요구하는 응용프로그램을 설치하는 것을 방지한다. 그러나 응용프로그램이 해당 기능이 있거나 없거나 작동할 수 있다면 키를 포함하지 않아야 한다. 이 키를 설정하는 것에 대한 더 많은 정보는, "필수적인 장치 기능 선언하기"를 보라.

표 1-2는 어떤 형식의 하드웨어가 이용가능한지를 결정하기 위한 기술을 나열한다. 그 기능이 없어도 작동할 수 있지만 제공되면 사용하게 되는 경우에 이 기술들을 사용해야 한다.

표 1-2 이용가능한 하드웨어 기능 식별하기

Feature

Options

멀티태스킹이 되는지 결정하기 위해...

UIDevice 클래스에 있는 multitaskingSupported 속성의 값을 얻는다. 멀티태스킹 이용가능성을 결정하는데 대한 더 많은 정보는 "멀티태스킹 지원이 이용 가능한지 결정하기"를 보라.

인터페이스를 iPad-크기 화면으로 할지 iPhone-크기 화면으로 할지 결정하기 위해...

UIDevice 클래스의 userInterfaceIdiom 속성을 사용한다. 이 속성은 내용이 iPad를 위한 건지 iPhone과 iPod touch를 위한 건지에 따라 서로다른 배치를 지원하는 유니버셜 응용프로그램에만 적합하다. 유니버셜 응용프로그램을 구현하는데 대한 더 많은 정보는, iPad Programming Guide에 있는 "Starting Your Project"를 보라.

외부 화면이 붙어있는지 결정하기 위해...

UIScreen 클래스에 있는 screens 속성의 값을 얻는다. 그 배열은 하나 이상의 화면 객체를 가지며, 객체들 중에 하나는 메인 화면에 해당하고 다른 것은 외부 화면에 해당한다. 추가적인 화면을 사용하는데 대한 더 많은 정보는, UIScreen Class Reference를 보라.

하드웨어-수준 디스크 암호화가 이용가능한지 결정하기 위해...

공유되는 UIApplication 객체에 있는 protectedDataAvailable 속성의 값을 얻는다. 디스크 내용 암호화에 대한 더 많은 정보는, "보호된 파일로 작업하기"를 보라.

네트웍이 이용가능한지 결정하기 위해...

현재의 네트웍 연결성을 결정하는 System Configuration 프레임웍의 접근도 인터페이스를 사용한다. System Configuration 프레임웍을 어떻게 사용하는지의 예제는, Reachability를 보라. 

스틸 카메라가 이용가능한지 결정하기 위해...

카메라가 이용가능한지를 결정하기 위해 UIImagePickerController 클래스의 isSourceTypeAvailable: 메소드를 사용한다. 더 많은 정보는, Device Feature Programming Guide를 보라.

장치가 동영상을 찍을 수 있는지 결정하기 위해...

카메라가 이용가능한지 결정하기 위해 UIImagePickerController 클래스의 isSourceTypeAvailable: 메소드를 사용한 다음 UIImagePickerControllerSourceTypeCamera 원본에 대한 형식을 요청하기 위해 availableMediaTypesForSourceType: 메소드를 사용한다. 리턴된 배열이 kUTTypeMovie 키를 가진다면, 동영상 캡춰가 이용가능하다. 더 많은 정보는, Device Feature Programming Guide를 보라.

오디오 입력(마이크)을 이용가능한지 결정하기 위해...

iOS 3과 그 이후에는 오디오 입력이 이용가능한지 결정하기 위해 AVAudioSession 클래스를 사용한다. 이 클래스는 내장 마이크와 헤드폰 잭과 연결된 악세사리를 포함한 iOS-기반 장치 상의 많은 여러가지 원본의 오디오 입력에 대해 책임진다. 더 많은 정보는, AVAudioSession Class Reference를 보라.

GPS 하드웨어가 존재하는지 결정하기 위해...

응용프로그램에 업데이트 되는 위치를 전달하기 위해 CLLocationManager 객체를 설정할 때 고 정밀도 수준을 지정한다. Core Location 프레임웍은 특정한 하드웨어의 이용가능성에 대한 직접적인 정보를 제공하지는 않지만 대신에 필요한 데이터를 제공하기 위해 정확도 값을 사용한다. 이후의 위치 벤트에서 보고된 정확도가 불충분하다면, 사용자가 알도록 할 수 있다. 더 많은 정보는, Location Awareness Programming Guide를 보라.

특정 하드웨어 악세사리가 이용가능한지 결정하기 위해...

적절한 악세사리 객체를 찾고 거기에 연결하기 위해 External Accessory 프레임웍의 클래스들을 사용한다. 더 많은 정보는, External Accessory Programming Topics를 보라.

장치의 현재 배터리 잔량을 얻기 위해...

UIDevice 클래스의 batteryLevel 속성을 사용한다. 이 클래스에 대한 더 많은 정보는, UIDevice Class Reference를 보라.

근접 센서의 상태를 얻기 위해...

UIDevice 클래스의 proximityState 속성을 사용한다. 모든 장치가 근접 센서를 가진 것은 아니므로, 이 센서가 이용가능한지 결정하기 위해 proximityMonitoringEnabled 속성도 체크해야 한다. 이 클래스에 대한 더 많은 정보는 UIDevice Class Reference를 보라.

장치-수준이나 응용프로그램-수준 기능에 대한 일반적인 정보를 얻기 위해, UIDevice와 UIApplication 클래스의 메소드와 프로퍼티를 사용한다. 이들 클래스에 대한 더 많은 정보는, UIDevice Class Reference와 UIApplication Class Reference를 보라.

공유하기 버튼

 

1 2


구글광고수직

다음 웹인사이드

구글 analytics