iOS2012. 8. 7. 14:55



1. install XCode

2. install command line tools

  4.3이상에서는 아래 수행

  xcode-select -switch /Applications/Xcode.app 

3. install java developer package 

   https://developer.apple.com/downloads.

4. checkout webkit source

  svn checkout http://svn.webkit.org/repository/webkit/trunk WebKit

  or download http://nightly.webkit.org/files/WebKit-SVN-source.tar.bz2

5. update-webkit script 실행

 - 소스트리를 업데이트한다, 윈도우의 경우 추가적으로 필요한 라이브러리들을 업데이트한다.

6. build-webkit script 실행

$ cd WebkitSrc/Tools/Scripts

$ ./build-webkit

7. run-safari로 빌드된 webkit으로 safari실행

$ ./run-safari


디버깅 방법

xcode에서 디버기하려면 WebKit workspace를 이용한다. Product와 Intermediates위치를 빌드한 webkit과 일치시키려면 File->Workspace Settings -> Advanced button -> Custom -> Relative to Workspace 에 WebKitBuild를 Product와 Intermediates에 입력. Xcode preference의 custom build location을 지정하였다면 할필요 없구.


UIProcess디버깅

- WebKit2 Xcode project를 오픈

- Build Product Path설정

- Scheme 선택

- Edit Scheme -> Run -> Info pane -> Executable popup -> Other -> select /Applications/Safari.app

- Run



WebProcess디버깅

- Xcode에서는 WebKit workspace -> All Source(target WebProcess)를 선택하고, Run

- Commandline에서는 debug-safari 또는 debug-minibrowser script를 실행 --target-webprocess옵션을 붙여서 타겟지정. Safari나 mini browser상에서 실행이 됨.

Posted by 삼스
iOS2012. 7. 10. 14:19


디바이스별 화면구성요소 치수들에 대해 잘 정리된게 있어서 퍼왔숑~!

출처 : http://firejune.com/1723


iOS 기기용 웹앱이나 네이티브앱 개발시 유용하게 사용될 수 있는 치수들입니다. 특히, 모든 iOS 기기를 지원하는(유니버셜) 앱을 개발할 때 자주 찾게 되는 자료중 하나입니다. 스테이터스 바, 네비게이션 바, 탭 바,키보드 등의 사이즈를 세웠을 때와 눕혔을 때로 구분하여 측정했습니다.

아이폰의 화면 치수

아이폰에서 해상도를 계산할 때 굳이 레티나 디스플레이의 해상도(640 x 960)를 의식하여 계산할 필요는 없습니다. 단순히 이미지가 사용되는 곳에 더블픽셀(@x2)의 고해상도 이미지를 한 셋트 더 준비하면 된다는 사실만 기억하세요.

Portrait - 세웠을 때

앱 시작시 나타나는 오프닝 이미지는 기본으로 320 x 367 픽셀의 "filename.png"로 설정하고 레티나용으로 표시될 이미지는 640 x 734 픽셀의 "filename@2x.png"로 설정하면 됩니다.

iphone_portrait_dimensions.jpg
iPhone Portrait Width: 320px
iPhone Portrait Height: 480px

Status Bar Height: 20px
Nav Bar Height: 44px
Main Content Area Height: 367px
Tab Bar Height: 49px

Keyboard Height: 216px

iphone_portrait_keyboard_sizes.jpg
키보드가 나타난 상황에서는 메인 스크린의 일부와 탭바를 가립니다. 키보드 크기를 제외한 나머지 영역의 크기를 계산할 때 참고하세요.

Landscape - 눕혔을 때

아이폰을 눕혔을 때 나타나는 변화는 메인 컨텐츠 영역의 높이가 480에서 219픽셀로 줄어드는 것이고 네비게이션 바의 높이가 44에서 32픽셀로 줄어든다는 것입니다. 오프닝 이미지는 기본으로 480 x 219 픽셀 그리고 레티나용(@2x)은 960 x 438 픽셀입니다. 참고로 아이폰의 앱 시작 이미지는 세로와 가로 모두 준비할 필요가 없습니다. 자신의 앱이 가로와 세로 중 어디에 최적화 되어있는지를 판단하여 한가지만 준비하면 됩니다.

iphone_landscape_dimensions.jpg
iPhone Landscape Width: 480px
iPhone Landscape Height: 320px

Status Bar Height: 20px
Nav Bar Height: 32px
Main Content Area Height: 219px
Tab Bar Height: 49px

Keyboard Height: 162px

iphone_landscape_keyboard_sizes.jpg

아이패드의 화면 치수

아이패드는 아직 레티나 디스플레이를 지원하지 않기 때문에 더블픽셀(@2x) 이미지를 준비할 필요가 없습니다.

Portrait - 세웠을 때

ipad_portrait_dimensions.jpg
iPad Portrait Width: 768px
iPad Portrait Height: 1024px

Status Bar Height: 20px
Nav Bar Height: 44px
Main Content Area Height: 911px
Tab Bar Height: 49px

Keyboard Height: 264px

ipad_portrait_keyboard_sizes.jpg

Landscape - 눕혔을 때

아이폰과 달리 아이패드는 화면을 눕혔을 때 네비게이션 바의 높이에는 변화가 없습니다.

ipad_landscape_dimensions.jpg
iPad Landscape Width: 1024px
iPad Landscape Height: 768px

Status Bar Height: 20px
Nav Bar Height: 44px
Main Content Area Height: 655px
Tab Bar Height: 49px

Keyboard Height: 352px

ipad_landscape_keyboard_sizes.jpg

Posted by 삼스
iOS2012. 7. 3. 21:09


앱스토어 리뷰가이드라인 번역문과 원문.

[국문]

우리는 당신이 iOS를 위한 어플리케이션을 개발하려고 하는 것을 매우 기쁘게 생각합니다. iOS 앱 개발은 직업적, 금전적으로 수많은 개발자들에게 도움을 주고 있는 작업이며, 우리는 당신이 이 성공적인 개발자들의 대열에 합류하길 기원합니다. 우리가 앱스토어 리뷰 가이드라인을 작성한 것은 이번이 처음입니다. 우리는 이 리뷰가 당신이 앱을 개발하는데 발생할 수 있는 문제에 대해 명확한 지침을 제공해줄 수 있을거라고 기대하며, 그로 인해 앱 승인 절차를 빠르게 할 수 있을거라고 생각합니다.

우리는 앱을 책이나 노래 따위의 우리가 취급하지 않는 것들과는 다르게 보고 있습니다. 만약 당신이 종교를 비판하고 싶다면 책을 쓰십시오. 만약 당신이 섹스에 대해 묘사하고 싶다면 책을 쓰거나 노래를 만들거나, 혹은 의학적 서류를 만드십시오. 구분하기 다소 복잡할 수 있습니다만, 우리는 그런 류의 컨텐츠들을 앱스토어에 등록하지 못하도록 결정하였습니다. 하기의 지침들을 인지하는 것이 당신들의 앱 개발에 도움이 될 것입니다.

 많은 아이들이 앱들을 다운받고 있으며, 부모들이 별도로 아이들을 위한 컨트롤 장치를 세팅하지 않는 한 아이들의 앱
    다운로드를 제어할 수 있는 방법은 없습니다. (많은 부모들이 보통 그 장치를 세팅하지 않습니다.) 우리가 아이들에게 
    나쁜 영향을 주지 않도록 항상 주의하고 있음을 주지하십시오.


 앱스토어에는 250,000개가 넘는 앱들이 있습니다. 더 이상의 의미없는 앱들은 필요없습니다. 당신이 만든 앱이 실용적
    으로 쓸모있거나 혹은 지속적인 즐거움을 제공할 수 없다면 우리는 그 앱을 승인하지 않을 수 있습니다.


 만약 당신이 만든 앱이 고작 며칠 사이에 조잡하게 만들어졌다고 보이거나, 당신의 친구들에게 보여주기 위해 연습용
    으로 만든 앱을 스토어에 올릴 경우 해당 앱들은 승인 받지 못할 것입니다. 많은 전문 앱 개발자들은 자신들의 양질의 
    개발물이 아마추어들이 유희로 만든 것들과 같이 앱스토어에 전시되는 것을 원하지 않습니다.


 우리가 판단하기에 선을 넘었다고 보이는 컨텐츠나 행동을 다룬 앱은 승인을 거부당할 수 있습니다. 당신이 그 기준이 
    무엇이냐고 묻는다면, “보면 알것입니다.” 라고 대답하겠습니다. 우리는 당신들 역시 그 기준을 충분히 인식할 수 있을
    거라고 생각합니다.


 만약 당신의 앱이 승인을 거부당했을 경우, 당신은 우리가 제공하는 Review Board를 통해서 이를 어필할 수 있습니다. 
    당신이 이런 프로세스를 따르지 않고 언론사에 우리를 비난한다고해서 그 문제를 해결하지는 못할 것입니다.


 이 가이드라인은 지속적으로 업데이트될 수 있습니다. 만약 새로이 개발된 앱이 새로운 문제점을 야기할 경우 우리는 
    새 룰을 언제든 추가할 수 있습니다.

 어쩌면 당신이 만든 앱이 그것을 불러올지도 모릅니다.

 
마지막으로, 우리는 당신이 개발하는 앱을 매우 좋아하며 당신이 하는 일들에 존경심을 가지고 있습니다. 우리는 앱 개발에 있어서 당신의 능력을 최대한 발휘할 수 있는 최고의 플랫폼을 구축할 수 있도록 노력하고 있습니다. 어쩌면 당신이 보기에 우리의 통제가 지나치다고 생각할지도 모르지만, 만약 그렇다면 그건 우리가 고객의 입장에서 생각하고 그들이 우리의 제품을 통해 양질의 경험을 할 수 있도록 신경쓰기 때문 일 겁니다. 그런 생각은 당신들 대부분도 아마 마찬가지일겁니다.
목차
1. 약관
2. 기능성
3. 메타데이터, 등급, 순위
4. 지역
5. 알림서비스 (푸쉬 노티피케이션)
6. 게임센터
7. 전자광고
8. 상표, 상품외장
9. 미디어 컨텐츠
10. 유저 인터페이스
11. 구입, 통화
12. 긁어오기, 종합
13. 기기에 손상
14. 개인적인 공격
15. 폭력성
16. 거부감을 주는 컨텐츠
17. 사생활
18. 포르노그래피
19. 종교, 문화, 인종
20. 컨테스트, 경품, 복권, 추첨
21. 자선, 기부
22. 법적 요구사항
1. 약관
1.1     앱스토어의 어플리케이션을 개발하는 개발자로서 당신은 Program License Agreement (PLA), Human Interface 
          Guidelines (HIG), 그 외에 다른 애플과 맺은 라이센스 혹은 계약들에 종속된다. 하기의 룰과 예시는 당신이 만드는 
          앱이 승인을 받는데 도움을 주기 위한 것이지 다른 협의문을 수정하거나 그에 종속된 조항을 무효화하기 위함이 
          아니다.
2. 기능성

2.1     (시스템을) 고장내는 앱은 승인하지 않는다.
2.2     버그가 발견되는 앱은 승인하지 않는다.
2.3     개발자가 명시한대로 작동하지 않는 앱은 승인하지 않는다.
2.4     문서 상의 설명과는 일치하지 않는 숨겨진 요소 혹은 불법적 요소를 포함한 앱은 승인하지 않는다.
2.5     공개되지 않은 API(어플리케이션 프로그래밍 인터페이스)를 사용한 앱은 승인하지 않는다.
2.6     할당된 공간 외의 곳에서 데이터를 읽거나 쓰는 앱은 승인하지 않는다.
2.7     어떤 방식이나 형태로든 코드를 다운받는 앱은 승인하지 않는다.
2.8     다른 실행 가능한 코드를 인스톨 혹은 실행시키는 앱은 승인하지 않는다.
2.9     “베타”, “데모”, “체험판” 혹은 “테스트” 버전인 앱들은 승인하지 않는다.
2.10   아이폰 앱은 별도의 조정없이 아이패드에서도 사용할 수 있어야한다. 해상도는 아이폰과 동일, 아이폰3GS의 2배
          이다.
2.11   앱스토어에 이미 있는, 그중에서도 특히 유사한 종류 여럿이 존재하는 앱을 복제한 앱은 승인하지 않는다. 
2.12   실용적으로 유용하지 않거나 지속적인 오락적 가치를 제공하지 못하는 앱은 승인하지 않는다.
2.13   마케팅이나 광고가 주목적으로 제작된 앱은 승인하지 않는다.
2.14   명확하게 명시되지 않은 속임 혹은 가짜 기능을 제공하기 위해 만들어진 앱은 승인하지 않는다.
2.15   20메가가 넘는 크기의 앱은 무선 네트워크를 통해서 다운로드할 수 없다. (앱스토어에서 자동적으로 이를 방지함)
2.16   멀티태스킹 앱은 백그라운드 서비스를 그것들의 기본적인 목적에 맞게 사용해야한다. 
          (예: 인터넷전화, 오디오 플레이백, 지역, 과제수행, 지역 공지 등)
2.17   웹브라우징하는 앱은 IOS WebKit framework와 WebKit Javascript를 반드시 사용해야한다.
2.18   알코올 혹은 법적으로 금지된 물질의 과도한 소비를 조장하거나, 미성년자의 음주 및 흡연을 조장하는 앱은 승인
          하지 않는다.
2.19   잘못된 진단결과 혹은 기타 부정확한 기기 정보를 제공하는 앱은 승인하지 않는다.
2.20   앱스토어에 유사한 앱의 여러가지 버전을 올려서 “스팸질”을 하는 개발자는 iOS 개발자 프로그램에서 퇴출한다.

3. 메타데이터 (이름, 설명, 등급, 순위 등)
3.1     다른 모바일 플랫폼의 이름을 명시한 메타데이터를 포함한 앱은 승인하지 않는다. 
3.2     플레이스홀더 텍스트를 포함한 앱은 승인하지 않는다. 
3.3     앱 설명에서 앱 컨텐츠, 기능과 상관없는 기술을 한 앱은 승인하지 않는다. 
3.4     아이튠스 커넥트 상에 표시되는 앱의 이름과 기기 상에 표시되는 앱의 이름은 서로 비슷해야한다. 
          이는 혼란을 피하기 위한 목적이다. 
3.5     앱의 큰 아이콘과 작은 아이콘은 혼란을 피하기 위해 서로 비슷해야한다. 
3.6     4세 이상 등급을 지키지 않은 앱 아이콘과 스크린샷을 포함한 앱은 승인하지 않는다. 
3.7     앱 컨텐츠에 맞지 않는 카테고리, 장르를 표기한 앱은 승인하지 않는다. 
3.8     개발자는 자신의 앱에 적합한 등급을 매길 책임이 있다. 부적합한 등급은 애플이 수정할 수 있다. 
3.9     개발자는 자신의 앱에 적합한 키워드를 부여할 책임이 있다. 부적합한 키워드는 애플이 수정하거나 삭제할 수 
          있다.
3.10   거짓 리뷰, 돈을 주고 작성한 리뷰, 혹은 기타 부적합한 방법으로 유저 리뷰 혹은 앱스토어 상의 차트 순위를 조작
          하거나 부풀리려는 시도를 한 개발자는 iOS 개발자 프로그램에서 퇴출한다.
4. 지역
4.1     지역 데이터를 수집, 전송, 혹은 사용하기 전에 해당사항에 관해 사용자의 합의를 공지하지 않거나 득하지 않은 
          앱은 승인하지 않는다.
4.2     지역 데이터에 근거한 API를 통해 자동차, 비행기 혹은 기타 기기들의 자동, 자주적인 조작을 하고자 하는 앱은
          승인하지 않는다.
4.3     지역 데이터에 근거한 API를 통해 발송, 차량관리, 혹은 긴급 서비스를 하고자 하는 앱은 승인하지 않는다.
5. 알림서비스 (푸쉬 노티피케이션)
5.1     APN(애플 푸쉬 노티피케이션) API를 사용하지 않은 알림서비스를 제공하는 앱은 승인하지 않는다.
5.2     애플로부터 푸쉬 어플리케이션 ID를 득하지 않고 APN 서비스를 사용하는 앱은 승인하지 않는다.
5.3     사용자 합의를 먼저 득하지 않고 알림서비스를 보내는 앱은 승인하지 않는다.
5.4     알림서비스를 통해 민감한 개인정보, 혹은 비밀정보를 보내는 앱은 승인하지 않는다.
5.5     알림서비스를 통해 원하지 않는 메시지를 전하거나, 피싱 혹은 스팸의 목적으로 만들어진 앱은 승인하지 않는다.
5.6     앱의 알림서비스를 이용하여 광고, 프로모션, 혹은 어떠한 직접적 마케팅도 해서는 안된다.
5.7     앱의 알림서비스 사용료를 사용자들로 하여금 부담하게 해서는 안된다.
5.8     알림서비스를 통해 네트워크 용량 혹은 APN 서비스의 대역폭을 과도하게 사용하거나 기기에 지나친 부담을 주는 
          앱은 승인하지 않는다.
5.9     바이러스, 파일, 컴퓨터 코드, 혹은 APN 서비스의 정상적인 기동을 방해하거나 손상을 끼치는 프로그램을 전송하는 
          앱은 승인하지 않는다.
6. 게임센터
6.1     플레이어 ID를 최종사용자 혹은 제3자에게 보여주는 앱은 승인하지 않는다. 
6.2     어떠한 목적으로든 플레이어 ID를 사용하는 앱은 승인하지 않는다. 단, 그것이 게임센터 약관에 근거하였을 경우는 
          논외로 한다.
6.3     룩업, 트레이스, 릴레이트, 어소시에이트, 마인, 하베스트 등을 역추적하여 플레이어 ID, 가명 혹은 기타 게임센터를
          통해 얻을 수 있는 정보를 이용하고자 하는 개발자는 iOS 개발자 프로그램에서 퇴출한다.
6.4     순위권 점수 따위의 게임센터 정보는 게임센터의 승인을 받은 앱에서만 사용할 수 있다.
6.5     게임센터 서비스를 통해 원하지 않는 메시지를 전하거나, 피싱 혹은 스팸의 목적으로 만들어진 앱은 승인하지 
          않는다.
6.6     게임센터 서비스를 통해 네트워크 용량 혹은 APN 서비스의 대역폭을 과도하게 사용하는 앱은 승인하지 않는다.
6.7     바이러스, 파일, 컴퓨터 코드, 혹은 게임센터 서비스의 정상적인 기동을 방해하거나 손상을 끼치는 프로그램을 
          전송하는 앱은 승인하지 않는다.
7. 전자광고
7.1     인위적으로 광고의 시청수나 조회수를 올리고자 하는 앱은 승인하지 않는다.
7.2     아무 내용이 없는 전자광고 배너를 달고 있는 앱은 승인하지 않는다.
7.3     광고를 보여주는 것이 주목적인 앱은 승인하지 않는다.
8. 상표, 상품외장
8.1     개발자들은 애플 상표 및 저작권 사용에 관한 가이드라인과 애플 상표 리스트에 명시된 모든 약관에 근거하여 앱을 
          제작해야 한다.
8.2     애플이 앱의 소스나 공급자라고 주장하거나 애플이 앱의 품질이나 기능을 보증한다는 내용을 주장 혹은 암시하는 
          앱은 승인하지 않는다.
8.3     애플 제품이나 광고 주제와 혼동할 수 있을 정도로 유사한 앱은 승인하지 않는다.
8.4     앱 이름 상에 애플 제품 이름의 철자를 잘못 적었을 경우 (예, GPS for Iphone, iTuz) 해당 앱은 승인하지 않는다.
8.5     법적으로 보장되는 제3자의 권리(상표, 저작권, 기업비밀, 기타 등록된 컨텐츠)를 사용할 경우 요청 시 서류화된
          사용권을 제출해야한다.
8.6     오리지널 컨텐츠의 기능에 변화가 없고 해당 브랜드에 관해 모든 것을 명확히 확인할 수 있다는 전제 하에서 구글 
          맵스 API를 통해 습득한 구글 맵스 및 구글 어스 이미지는 어플리케이션 내에서 사용할 수 있다.
9. 미디어 컨텐츠
9.1     음악 라이브러리에 접속 시 MediaPlayer framework를 사용하지 않는 앱은 승인하지 않는다.
9.2     아이팟 인터페이스를 흉내낸 사용자 인터페이스를 가진 앱은 승인하지 않는다.
9.3     무선 네트워크를 통한 오디오 스트리밍 컨텐츠는 5분 간 5메가 이상 사용하지 않도록 한다.
9.4     무선 네트워크를 통한 비디오 스트리밍 컨텐츠는 10분을 초과하는 경우 HTTP 라이브 스트리밍을 사용해야하며, 
          기본 64kbps 오디오만 사용한 HTTP 라이브 스트림을 포함해야한다.
10. 사용자 인터페이스
10.1   모든 앱은 애플 아이폰 Human Interface Guidelines과 애플 아이패드 Human Interface Guidelines에 맞춰 제작해야 
          한다.
10.2   앱스토어, 아이튠스스토어, 아이북스토어를 포함한 아이폰 상에 기본으로 제공되는 번들 앱과 유사한 앱은 승인
          하지 않는다.
10.3   애플 아이폰 Human Interface Guidelines과 애플 아이패드 Human Interface Guidelines에 명시된대로 버튼이나 
          아이콘 등을 제대로 제공하는 시스템이 없는 앱은 승인하지 않는다.
10.4   변경된 데스크탑/홈 스크린 환경을 만들거나 멀티앱 위젯 환경을 시뮬레이션하는 앱은 승인하지 않는다.
10.5   볼륨 업/다운 및 벨소리/진동 스위치 같은 기본적인 스위치 기능을 변경하는 앱은 승인하지 않는다.
10.6   애플과 애플의 고객들은 심플하고 세련되며 창의적이고 좋은 아이디어에서 나온 인터페이스를 높이 평가한다. 
          이러한 인터페이스를 만들기 위해서는 더 많은 노력이 필요하지만, 그럴만한 가치가 있는 일이다. 
          인터페이스에 관한 애플의 기준치는 높다. 
          만약 당신의 사용자 인터페이스가 복잡하거나 좋지 않을 경우 해당 앱을 승인하지 않을 것이다.
11. 구입, 통화
11.1   락을 풀어서 앱스토어 이외의 메커니즘에서 추가적인 기능을 사용할 수 있도록 하는 앱은 승인하지 않는다.
11.2   앱 상의 구매 API (IAP) 이외의 시스템을 통해 앱 상의 컨텐츠, 기능, 혹은 서비스를 구매할 수 있도록 하는 앱은
          승인하지 않는다.
11.3   IAP를 통해 어플리케이션 외에서 쓰이는 상품이나 서비스를 구입할 수 있도록 하는 앱은 승인하지 않는다.
11.4   IAP를 통해 신용이나 다른 통화를 구입하는 앱의 경우 해당 신용을 어플리케이션 내에서 소비해야한다.
11.5   IAP를 통해 만료된 신용이나 다른 통화를 구입하는 앱은 승인하지 않는다.
11.6   IAP를 통한 컨텐츠 가입은 최소 30일 동안 유지되어야하며, iOS를 사용하는 기기를 가진 모든 사용자들에게 공개
          되어야한다.
11.7   IAP를 통해 물품을 구입하는 앱의 경우 정확한 구입기능이 있어야한다.
11.8   IAP를 통해 카메라나 자이로스코프 따위의 iOS에 내장된 기능에 접속할 수 있는 권한을 구매할 수 있도록 하는 앱은 
          승인하지 않는다.
11.9   “렌탈” 컨텐츠나 일정 기간이 지나면 만료되는 서비스를 포함한 앱은 승인하지 않는다.
11.10   보험 어플리케이션은 무료여야하며, 배포되는 지역의 법을 준수해야한다. 또한, 해당 앱은 IAP를 사용할 수 없다.
11.11   전반적으로, 당신이 만든 앱이 비쌀수록 우리는 더 철저하게 리뷰를 할 것이다.
12. 긁어오기, 종합
12.1   애플 사이트(예: apple.com, 아이튠스스토어, 앱스토어, 아이튠스커넥트, 애플 개발자 프로그램 등)로부터 정보를
          긁어오거나 애플 사이트와 서비스의 컨텐츠를 이용해서 순위를 만드는 앱은 승인하지 않는다.
12.2   어플리케이션은 아이튠스스토어 RSS feed 따위의 승인받은 애플 RSS feeds를 사용해야 한다.
12.3   웹상의 자료를 잘라온 것이나 컨텐츠 모음, 혹은 링크모음 따위의 앱은 승인하지 않는다.
13. 기기에 손상
13.1   사용자들로 하여금 애플 기기를 기기를 손상시키는 방향으로 사용하게 유도하는 앱은 승인하지 않는다.
13.2   기기의 배터리를 급격히 소모시키거나 과도한 열을 발생시키는 앱은 승인하지 않는다.
14. 개인적인 공격
14.1   명예훼손, 공격적, 비열한 내용을 포함하거나 혹은 특정인이나 집단에게 해를 끼칠 수 있는 앱은 승인하지 않는다.
14.2   직업적 정치 풍자가나 유머작가는 공격적, 비열한 코멘트로 인한 금지 항목에서 제외한다.
15. 폭력성
15.1   사람이나 짐승이 살해당하는 모습, 불구가 되는 모습, 총에 맞는 모습, 칼에 찔리는 모습, 고문당하거나 다치는
          모습의 실제 이미지를 표현한 앱은 승인하지 않는다.
15.2   폭력이나 아동학대를 묘사한 앱은 승인하지 않는다.
15.3   게임 상의 “적”은 특정인종, 문화, 실존하는 정부나 회사, 혹은 그 어떤 실제적 존재를 단독으로 지목하여 만들어서
          는 안된다.
15.4   무기를 통한 폭력을 현실적으로 보여줘서 무기의 불법적, 난폭한 사용을 독려하는 앱은 승인하지 않는다.
15.5   러시안 룰렛을 포함한 앱은 승인하지 않는다.
16. 거부감을 주는 컨텐츠
16.1   과도하게 거부감을 주거나 상스러운 컨텐츠를 보여주는 앱은 승인하지 않는다.
16.2   주로 사용자를 기분나쁘게 하거나 역겹게 하기 위한 목적으로 제작된 앱은 승인하지 않는다.
17. 사생활
17.1   모든 앱은 사용자 정보 사용에 관해 사전에 사용자의 허락없이, 그리고 사용자로 하여금 해당 정보가 어디서 어떻게 
          사용될 것인지에 관해 알려주지 않은 채 사용자 정보를 전송할 수 없다.
17.2   구동을 위해서 이메일 주소나 생년월일 따위의 사용자 개인정보의 공유를 필요로 하는 앱은 승인하지 않는다.
17.3   미성년자를 대상으로 정보수집을 하는 앱은 승인하지 않는다.
18. 포르노그래피
18.1   웹스터 사전에서 정의한 “생식기관의 노골적 묘사, 그리고 미적이나 감성적인 느낌이 아닌 에로틱한 느낌을 유발
          하기 위한 목적의 노골적 행위를 표현한 것”에 해당하는 포르노물을 포함한 앱은 승인하지 않는다.
18.2   수시로 포르노물에 해당하는 내용이 등장하는 사용자 제작 컨텐츠를 포함하는 앱(예: “채트 룰렛” 앱)은 승인하지 
          않는다.
19. 종교, 문화, 인종
19.1   특정 종교, 문화, 혹은 인종에 대해 명예훼손, 공격적, 비열한 태도를 취하고 있거나 해당 그룹에게 피해를 끼칠 수 
          있는 코멘트 혹은 문헌을 포함한 앱은 승인하지 않는다.
19.2   앱이 종교적인 텍스트를 포함할 경우, 텍스트 상의 멘트나 번역은 정확해야한다. 코멘트는 선동적이라기보다는 
          교육적이거나 정보전달 차원에서 그쳐야한다.
20. 컨테스트, 경품, 복권, 추첨
20.1   경품 및 컨테스트는 앱의 개발자/회사가 후원하여 제공해야한다.
20.2   경품 및 컨테스트에 관한 공식적인 룰이 앱 상에 표기되어야하며, 해당 행위에 관해 애플이 관련이 없다는 점을 
          명확히 해야한다.
20.3   복권 앱을 만들기 위해서는 개발자가 법적 허가를 득해야하며, 복권 앱은 해당 3가지 특성을 모두 갖추고 있어야
          한다: 배려, 기회, 상금
20.4   사용자로 하여금 직접적으로 복권이나 추첨티켓을 살 수 있도록 하는 앱은 승인하지 않는다.
21. 자선, 기부
21.1   자선단체에 기부할 수 있는 기능을 포함한 앱은 무료여야한다.
21.2   기부금의 모금은 사파리 상의 웹사이트나 SMS를 통해 이뤄져야한다.
22. 법적 요구사항
22.1   앱은 사용자에게 공개되는 지역의 법적 요구사항을 충족시켜야한다. 모든 지역법을 이해하고 따르는 것은 개발자
          들의 의무사항이다.
22.2   허위사실, 사기, 호도된 정보를 포함한 앱은 승인하지 않는다.
22.3   범죄 혹은 난폭한 행위를 요청, 촉진, 장려하는 앱은 승인하지 않는다.
22.4   불법적 파일 공유를 가능케하는 앱은 승인하지 않는다.
22.5   카드 카운터를 포함한 불법적 도박을 조장하기 위해 만들어진 앱은 승인하지 않는다.
22.6   익명 혹은 장난스러운 전화나 SMS/MMS 메시지 전송이 가능한 앱은 승인하지 않는다.
22.7   부정한 방법으로 사용자의 패스워드나 기타 개인정보를 알아내고자 하는 목적으로 앱을 만든 개발자는 iOS 개발자 
          프로그램에서 퇴출한다.
이 문서는 지속적으로 업데이트되는 문서임
이 문서는 개발자들이 앱스토어에 제출하는 앱을 우리가 어떻게 리뷰하는지 알려줍니다. 또한 우리는 이 가이드가 당신이 앱을 개발하고 제출하는데에 있어 도움이 될 수 있기를 바랍니다. 이 가이드는 새로운 앱과 상황이 발생함에 따라 지속적으로 업데이트되는 문서이며, 변경사항이 있을 경우 주기적으로 이를 반영할 계획입니다.

iOS의 앱 개발에 참여해주셔서 감사합니다. 비록 이 문서가 당신이 하지 말아야할 것들로 가득하긴 하지만, 그보다 훨씬 짧더라도 당신이 꼭 해야하는 것들의 리스트를 꼭 기억해두시길 바랍니다. 무엇보다도, 사용자들을 놀라게 하고 기쁘게 하는 것에 동참 해주시길 바랍니다. 그들에게 창조적인 길을 보여주고, 이전에는 볼 수 없었던 방법으로 소통할 수 있도록 해주십시오. 우리의 경험에 의하면 사용자들은 기능적으로나 사용자 인터페이스적으로 세련된 것에 적극적으로 반응합니다. 조금 더 노력하셔서 그들에게 그들이 기대하는 이상을 보여주십시오. 그들이 이전까지 본 적이 없는 세계를 보여주시기 바랍니다. 우리는 당신을 도울 준비가 되어있습니다.


[원문]

Introduction

We're pleased that you want to invest your talents and time to develop applications for iOS. It has been a rewarding experience - both professionally and financially - for tens of thousands of developers and we want to help you join this successful group. We have published our App Store Review Guidelines in the hope that they will help you steer clear of issues as you develop your app and speed you through the approval process when you submit it.

We view Apps different than books or songs, which we do not curate. If you want to criticize a religion, write a book. If you want to describe sex, write a book or a song, or create a medical app. It can get complicated, but we have decided to not allow certain kinds of content in the App Store. It may help to keep some of our broader themes in mind:

  • We have lots of kids downloading lots of apps, and parental controls don't work unless the parents set them up (many don't). So know that we're keeping an eye out for the kids.
  • We have over 350,000 apps in the App Store. We don't need any more Fart apps. If your app doesn't do something useful or provide some form of lasting entertainment, it may not be accepted.
  • If your App looks like it was cobbled together in a few days, or you're trying to get your first practice App into the store to impress your friends, please brace yourself for rejection. We have lots of serious developers who don't want their quality Apps to be surrounded by amateur hour.
  • We will reject Apps for any content or behavior that we believe is over the line. What line, you ask? Well, as a Supreme Court Justice once said, "I'll know it when I see it". And we think that you will also know it when you cross it.
  • If your app is rejected, we have a Review Board that you can appeal to. If you run to the press and trash us, it never helps.
  • If you attempt to cheat the system (for example, by trying to trick the review process, steal data from users, copy another developer's work, or manipulate the ratings) your apps will be removed from the store and you will be expelled from the developer program.
  • This is a living document, and new apps presenting new questions may result in new rules at any time. Perhaps your app will trigger this.

Lastly, we love this stuff too, and honor what you do. We're really trying our best to create the best platform in the world for you to express your talents and make a living too. If it sounds like we're control freaks, well, maybe it's because we're so committed to our users and making sure they have a quality experience with our products. Just like almost all of you are too.

Table of Contents

  1. Terms and conditions
  2. Functionality
  3. Metadata, ratings and rankings
  4. Location
  5. Push notifications
  6. Game Center
  7. iAd
  8. Trademarks and trade dress
  9. Media content
  10. User interface
  11. Purchasing and currencies
  12. Scraping and aggregation
  13. Damage to device
  14. Personal attacks
  15. Violence
  16. Objectionable content
  17. Privacy
  18. Pornography
  19. Religion, culture, and ethnicity
  20. Contests, sweepstakes, lotteries, and raffles
  21. Charities and contributions
  22. Legal requirements

1. Terms and conditions

  • 1.1
    As a developer of applications for the App Store you are bound by the terms of the Program License Agreement (PLA), Human Interface Guidelines (HIG), and any other licenses or contracts between you and Apple. The following rules and examples are intended to assist you in gaining acceptance for your app in the App Store, not to amend or remove provisions from any other agreement.

2. Functionality

  • 2.1
    Apps that crash will be rejected
  • 2.2
    Apps that exhibit bugs will be rejected
  • 2.3
    Apps that do not perform as advertised by the developer will be rejected
  • 2.4
    Apps that include undocumented or hidden features inconsistent with the description of the app will be rejected
  • 2.5
    Apps that use non-public APIs will be rejected
  • 2.6
    Apps that read or write data outside its designated container area will be rejected
  • 2.7
    Apps that download code in any way or form will be rejected
  • 2.8
    Apps that install or launch other executable code will be rejected
  • 2.9
    Apps that are "beta", "demo", "trial", or "test" versions will be rejected
  • 2.10
    iPhone apps must also run on iPad without modification, at iPhone resolution, and at 2X iPhone 3GS resolution
  • 2.11
    Apps that duplicate apps already in the App Store may be rejected, particularly if there are many of them, such as fart, burp, flashlight, and Kama Sutra apps.
  • 2.12
    Apps that are not very useful, are simply web sites bundled as apps, or do not provide any lasting entertainment value may be rejected
  • 2.13
    Apps that are primarily marketing materials or advertisements will be rejected
  • 2.14
    Apps that are intended to provide trick or fake functionality that are not clearly marked as such will be rejected
  • 2.15
    Apps larger than 20MB in size will not download over cellular networks (this is automatically prohibited by the App Store)
  • 2.16
    Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.
  • 2.17
    Apps that browse the web must use the iOS WebKit framework and WebKit Javascript
  • 2.18
    Apps that encourage excessive consumption of alcohol or illegal substances, or encourage minors to consume alcohol or smoke cigarettes, will be rejected
  • 2.19
    Apps that provide incorrect diagnostic or other inaccurate device data will be rejected
  • 2.20
    Developers "spamming" the App Store with many versions of similar apps will be removed from the iOS Developer Program
  • 2.21
    Apps that are simply a song or movie should be submitted to the iTunes store. Apps that are simply a book should be submitted to the iBookstore.
  • 2.22
    Apps that arbitrarily restrict which users may use the app, such as by location or carrier, may be rejected
  • 2.23
    Apps must follow the iOS Data Storage Guidelines or they will be rejected
  • 2.24
    Apps that are offered in Newsstand must comply with schedules 1, 2 and 3 of the Developer Program License Agreement or they will be rejected

3. Metadata (name, descriptions, ratings, rankings, etc)

  • 3.1
    Apps or metadata that mentions the name of any other mobile platform will be rejected
  • 3.2
    Apps with placeholder text will be rejected
  • 3.3
    Apps with descriptions not relevant to the application content and functionality will be rejected
  • 3.4
    App names in iTunes Connect and as displayed on a device should be similar, so as not to cause confusion
  • 3.5
    Small and large app icons should be similar, so as to not to cause confusion
  • 3.6
    Apps with app icons and screenshots that do not adhere to the 4+ age rating will be rejected
  • 3.7
    Apps with Category and Genre selections that are not appropriate for the app content will be rejected
  • 3.8
    Developers are responsible for assigning appropriate ratings to their apps. Inappropriate ratings may be changed/deleted by Apple
  • 3.9
    Developers are responsible for assigning appropriate keywords for their apps. Inappropriate keywords may be changed/deleted by Apple
  • 3.10
    Developers who attempt to manipulate or cheat the user reviews or chart ranking in the App Store with fake or paid reviews, or any other inappropriate methods will be removed from the iOS Developer Program
  • 3.11
    Apps which recommend that users restart their iOS device prior to installation or launch may be rejected
  • 3.12
    Apps should have all included URLs fully functional when you submit it for review, such as support and privacy policy URLs

4. Location

  • 4.1
    Apps that do not notify and obtain user consent before collecting, transmitting, or using location data will be rejected
  • 4.2
    Apps that use location-based APIs for automatic or autonomous control of vehicles, aircraft, or other devices will be rejected
  • 4.3
    Apps that use location-based APIs for dispatch, fleet management, or emergency services will be rejected
  • 4.4
    Location data can only be used when directly relevant to the features and services provided by the app to the user or to support approved advertising uses

5. Push notifications

  • 5.1
    Apps that provide Push Notifications without using the Apple Push Notification (APN) API will be rejected
  • 5.2
    Apps that use the APN service without obtaining a Push Application ID from Apple will be rejected
  • 5.3
    Apps that send Push Notifications without first obtaining user consent will be rejected
  • 5.4
    Apps that send sensitive personal or confidential information using Push Notifications will be rejected
  • 5.5
    Apps that use Push Notifications to send unsolicited messages, or for the purpose of phishing or spamming will be rejected
  • 5.6
    Apps cannot use Push Notifications to send advertising, promotions, or direct marketing of any kind
  • 5.7
    Apps cannot charge users for use of Push Notifications
  • 5.8
    Apps that excessively use the network capacity or bandwidth of the APN service or unduly burden a device with Push Notifications will be rejected
  • 5.9
    Apps that transmit viruses, files, computer code, or programs that may harm or disrupt the normal operation of the APN service will be rejected

6. Game Center

  • 6.1
    Apps that display any Player ID to end users or any third party will be rejected
  • 6.2
    Apps that use Player IDs for any use other than as approved by the Game Center terms will be rejected
  • 6.3
    Developers that attempt to reverse lookup, trace, relate, associate, mine, harvest, or otherwise exploit Player IDs, alias, or other information obtained through the Game Center will be removed from the iOS Developer Program
  • 6.4
    Game Center information, such as Leaderboard scores, may only be used in apps approved for use with the Game Center
  • 6.5
    Apps that use Game Center service to send unsolicited messages, or for the purpose of phishing or spamming will be rejected
  • 6.6
    Apps that excessively use the network capacity or bandwidth of the Game Center will be rejected
  • 6.7
    Apps that transmit viruses, files, computer code, or programs that may harm or disrupt the normal operation of the Game Center service will be rejected

7. iAd

  • 7.1
    Apps that artificially increase the number of impressions or click-throughs of ads will be rejected
  • 7.2
    Apps that contain empty iAd banners will be rejected
  • 7.3
    Apps that are designed predominantly for the display of ads will be rejected

8. Trademarks and trade dress

  • 8.1
    Apps must comply with all terms and conditions explained in the Guidelines for Using Apple Trademarks and Copyrights and the Apple Trademark List
  • 8.2
    Apps that suggest or infer that Apple is a source or supplier of the app, or that Apple endorses any particular representation regarding quality or functionality will be rejected
  • 8.3
    Apps which appear confusingly similar to an existing Apple product or advertising theme will be rejected
  • 8.4
    Apps that misspell Apple product names in their app name (i.e., GPS for Iphone, iTunz) will be rejected
  • 8.5
    Use of protected 3rd party material (trademarks, copyrights, trade secrets, otherwise proprietary content) requires a documented rights check which must be provided upon request
  • 8.6
    Google Maps and Google Earth images obtained via the Google Maps API can be used within an application if all brand features of the original content remain unaltered and fully visible. Apps that cover up or modify the Google logo or copyright holders identification will be rejected

9. Media content

  • 9.1
    Apps that do not use the MediaPlayer framework to access media in the Music Library will be rejected
  • 9.2
    App user interfaces that mimic any iPod interface will be rejected
  • 9.3
    Audio streaming content over a cellular network may not use more than 5MB over 5 minutes
  • 9.4
    Video streaming content over a cellular network longer than 10 minutes must use HTTP Live Streaming and include a baseline 64 kbps audio-only HTTP Live stream

10. User interface

  • 10.1
    Apps must comply with all terms and conditions explained in the Apple iOS Human Interface Guidelines
  • 10.2
    Apps that look similar to apps bundled on the iPhone, including the App Store, iTunes Store, and iBookstore, will be rejected
  • 10.3
    Apps that do not use system provided items, such as buttons and icons, correctly and as described in the Apple iOS Human Interface Guidelines may be rejected
  • 10.4
    Apps that create alternate desktop/home screen environments or simulate multi-app widget experiences will be rejected
  • 10.5
    Apps that alter the functions of standard switches, such as the Volume Up/Down and Ring/Silent switches, will be rejected
  • 10.6
    Apple and our customers place a high value on simple, refined, creative, well thought through interfaces. They take more work but are worth it. Apple sets a high bar. If your user interface is complex or less than very good, it may be rejected

11. Purchasing and currencies

  • 11.1
    Apps that unlock or enable additional features or functionality with mechanisms other than the App Store will be rejected
  • 11.2
    Apps utilizing a system other than the In App Purchase API (IAP) to purchase content, functionality, or services in an app will be rejected
  • 11.3
    Apps using IAP to purchase physical goods or goods and services used outside of the application will be rejected
  • 11.4
    Apps that use IAP to purchase credits or other currencies must consume those credits within the application
  • 11.5
    Apps that use IAP to purchase credits or other currencies that expire will be rejected
  • 11.6
    Content subscriptions using IAP must last a minimum of 7 days and be available to the user from all of their iOS devices
  • 11.7
    Apps that use IAP to purchase items must assign the correct Purchasability type
  • 11.8
    Apps that use IAP to purchase access to built-in capabilities provided by iOS, such as the camera or the gyroscope, will be rejected
  • 11.9
    Apps containing "rental" content or services that expire after a limited time will be rejected
  • 11.10
    Insurance applications must be free, in legal-compliance in the regions distributed, and cannot use IAP
  • 11.11
    In general, the more expensive your app, the more thoroughly we will review it
  • 11.12
    Apps offering subscriptions must do so using IAP, Apple will share the same 70/30 revenue split with developers for these purchases, as set forth in the Developer Program License Agreement.
  • 11.13
    Apps that link to external mechanisms for purchases or subscriptions to be used in the app, such as a “buy” button that goes to a web site to purchase a digital book, will be rejected
  • 11.14
    Apps can read or play approved content (specifically magazines, newspapers, books, audio, music, and video) that is subscribed to or purchased outside of the app, as long as there is no button or external link in the app to purchase the approved content. Apple will not receive any portion of the revenues for approved content that is subscribed to or purchased outside of the app

12. Scraping and aggregation

  • 12.1
    Applications that scrape any information from Apple sites (for example from apple.com, iTunes Store, App Store, iTunes Connect, Apple Developer Programs, etc) or create rankings using content from Apple sites and services will be rejected
  • 12.2
    Applications may use approved Apple RSS feeds such as the iTunes Store RSS feed
  • 12.3
    Apps that are simply web clippings, content aggregators, or a collection of links, may be rejected

13. Damage to device

  • 13.1
    Apps that encourage users to use an Apple Device in a way that may cause damage to the device will be rejected
  • 13.2
    Apps that rapidly drain the device's battery or generate excessive heat will be rejected

14. Personal attacks

  • 14.1
    Any app that is defamatory, offensive, mean-spirited, or likely to place the targeted individual or group in harms way will be rejected
  • 14.2
    Professional political satirists and humorists are exempt from the ban on offensive or mean-spirited commentary

15. Violence

  • 15.1
    Apps portraying realistic images of people or animals being killed or maimed, shot, stabbed, tortured or injured will be rejected
  • 15.2
    Apps that depict violence or abuse of children will be rejected
  • 15.3
    "Enemies" within the context of a game cannot solely target a specific race, culture, a real government or corporation, or any other real entity
  • 15.4
    Apps involving realistic depictions of weapons in such a way as to encourage illegal or reckless use of such weapons will be rejected
  • 15.5
    Apps that include games of Russian roulette will be rejected

16. Objectionable content

  • 16.1
    Apps that present excessively objectionable or crude content will be rejected
  • 16.2
    Apps that are primarily designed to upset or disgust users will be rejected

17. Privacy

  • 17.1
    Apps cannot transmit data about a user without obtaining the user's prior permission and providing the user with access to information about how and where the data will be used
  • 17.2
    Apps that require users to share personal information, such as email address and date of birth, in order to function will be rejected
  • 17.3
    Apps that target minors for data collection will be rejected

18. Pornography

  • 18.1
    Apps containing pornographic material, defined by Webster's Dictionary as "explicit descriptions or displays of sexual organs or activities intended to stimulate erotic rather than aesthetic or emotional feelings", will be rejected
  • 18.2
    Apps that contain user generated content that is frequently pornographic (ex "Chat Roulette" apps) will be rejected

19. Religion, culture, and ethnicity

  • 19.1
    Apps containing references or commentary about a religious, cultural or ethnic group that are defamatory, offensive, mean-spirited or likely to expose the targeted group to harm or violence will be rejected
  • 19.2
    Apps may contain or quote religious text provided the quotes or translations are accurate and not misleading. Commentary should be educational or informative rather than inflammatory

20. Contests, sweepstakes, lotteries, and raffles

  • 20.1
    Sweepstakes and contests must be sponsored by the developer/company of the app
  • 20.2
    Official rules for sweepstakes and contests, must be presented in the app and make it clear that Apple is not a sponsor or involved in the activity in any manner
  • 20.3
    It must be permissible by law for the developer to run a lottery app, and a lottery app must have all of the following characteristics: consideration, chance, and a prize
  • 20.4
    Apps that allow a user to directly purchase a lottery or raffle ticket in the app will be rejected

21. Charities and contributions

  • 21.1
    Apps that include the ability to make donations to recognized charitable organizations must be free
  • 21.2
    The collection of donations must be done via a web site in Safari or an SMS

22. Legal requirements

  • 22.1
    Apps must comply with all legal requirements in any location where they are made available to users. It is the developer's obligation to understand and conform to all local laws
  • 22.2
    Apps that contain false, fraudulent or misleading representations will be rejected
  • 22.3
    Apps that solicit, promote, or encourage criminal or clearly reckless behavior will be rejected
  • 22.4
    Apps that enable illegal file sharing will be rejected
  • 22.5
    Apps that are designed for use as illegal gambling aids, including card counters, will be rejected
  • 22.6
    Apps that enable anonymous or prank phone calls or SMS/MMS messaging will be rejected
  • 22.7
    Developers who create apps that surreptitiously attempt to discover user passwords or other private user data will be removed from the iOS Developer Program
  • 22.8
    Apps which contain DUI checkpoints that are not published by law enforcement agencies, or encourage and enable drunk driving, will be rejected

Living document

This document represents our best efforts to share how we review apps submitted to the App Store, and we hope it is a helpful guide as you develop and submit your apps. It is a living document that will evolve as we are presented with new apps and situations, and we'll update it periodically to reflect these changes.

Thank you for developing for iOS. Even though this document is a formidable list of what not to do, please also keep in mind the much shorter list of what you must do. Above all else, join us in trying to surprise and delight users. Show them their world in innovative ways, and let them interact with it like never before. In our experience, users really respond to polish, both in functionality and user interface. Go the extra mile. Give them more than they expect. And take them places where they have never been before. We are ready to help.

Posted by 삼스
iOS2012. 6. 14. 17:54


출처 : http://www.raywenderlich.com/3997/introduction-to-augmented-reality-on-the-iphone

This is a post by iOS Tutorial Team member and Forum Moderator Nick Waynik, a web and iOS developer in Pittsburgh, Pennsylvania.

Create a simple augmented reality game where you can blast some aliens!

Create a simple augmented reality game where you can blast some aliens!

iPhone/iPod에서 AR game을 간단하게 만드는 방법을 소개한다.

이겜은 카메라, 자이로스코프 그리고 cocos2d framework를 사용한다.

여러가지 기술들을 탐험할것이고 약간의 수학과 변환기술들이 언급될건데 겁먹지마! 별로 어렵지 않거든.

iPhone4이상이 필요하지 왜냐구? 자이로스코프땜에.

그리고 Cocos2D에 대한 기초지식과 Cocos2D를 이미 설치했어야 해. 알간? cocos2D를 전혀 모른다면 여길 ->  other Cocos2D tutorials 가바

시작하자!

Getting Started

Xcode열고 New/New Project. 그리고 iOS/cocos2d/cocos2d template선택해!, 다음눌러. project명은 ARSpaceships입력하고 다음, .. 머 암튼 프로젝트 생성하라고.

Space Shooter game의 일부 리소스를 사용하게 될거야 그건 여기(download them)서 다운받을 수 있지.

파일을 다운받았으면 폰트, 사운드 그리고 Spritesheets 폴더를 Resources그룹에 집어넣어. 폴더째로 이동시켜서.. 먼말인지 알지? 시킨대로 했다면 아래 그림처럼 보일겨.


A default Xcode project with the project resources added

We will use some of these items later on.

Roll the Camera!

앱을 당장 실행하고 싶다고? 안보는게 낳아. 까만스크린에 "Hello World"만 보일거야. AppDelegate.h를 열어서 UIView를 추가해!

UIView *overlay;

AppDelegate.m를 열어. EAGLView *glView가 보이는데까지 스크롤해. 그리고 pixelFormat을 kEAGLColorFormatRGBA8로 바꺼. 이렇게..

EAGLView *glView = [EAGLView viewWithFrame:[window bounds] 
    pixelFormat:kEAGLColorFormatRGBA8 depthFormat:0];

이거 안바꾸면 카메라가 암것도 표시하지 않는다네. 이건 AR겜이기때문에 그러면 안되지.

[window addSubview: viewController.view]; 코드 아래 다음코드를 넣을거야.

 
// set the background color of the view
[CCDirector sharedDirector].openGLView.backgroundColor = [UIColor clearColor];
[CCDirector sharedDirector].openGLView.opaque = NO;
 
// set value for glClearColor
glClearColor(0.0, 0.0, 0.0, 0.0);
 
// prepare the overlay view and add it to the window
overlay = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
overlay.opaque = NO;
overlay.backgroundColor=[UIColor clearColor];
[window addSubview:overlay];

여기서 우린 openGLView의 배경색을 클리어하기 위해 셋팅하지. 불투명하지 않게. glClearColor를 셋팅해서 말야. 그리고 마침내 overlay로 명명된 UIView를 생성해서 추가하고 있어. 우린 이걸 카메라를 위해 사용할거야.

다음엔 방금 추가한 코드 아래에 다음코드를 추가해~

#define CAMERA_TRANSFORM  1.24299
 
UIImagePickerController *uip;
 
@try {
    uip = [[[UIImagePickerController alloc] init] autorelease];
    uip.sourceType = UIImagePickerControllerSourceTypeCamera;
    uip.showsCameraControls = NO;
    uip.toolbarHidden = YES;
    uip.navigationBarHidden = YES;
    uip.wantsFullScreenLayout = YES;
    uip.cameraViewTransform = CGAffineTransformScale(uip.cameraViewTransform, 
        CAMERA_TRANSFORM, CAMERA_TRANSFORM);
}
@catch (NSException * e) {
    [uip release];
    uip = nil;
}
@finally {
    if(uip) {
        [overlay addSubview:[uip view]];
        [overlay release];
    }
}
 
[window bringSubviewToFront:viewController.view];

첫번째로, 카메라를 스케일링하기 위한 상수를 정의해. 카메라는 4:3의 비율이고 아이폰은 3:4기 때문에 우리는 카메라 이미지를 스케일링해야 하지.

두번째로, UIImagePickerController를 생성, 속성 설정, 스케일링하고 나서 overlay뷰에 추가해.

마지막으로 viewController를 카메라뷰의 앞으로 보이도록 가져와야 해. Cocos2D display를 포함하고 있지.

여기서 앱을 실행해바. 카메라화면위에 Hello World라는 글씨가 뵐겨.

The beginnings of an augmented reality app with Cocos2D!

Shake, Rattle, and Roll…Well at Least Yaw!

이제 좀더 어려운걸 해보자.

먼저 CoreMotion framework을 추가해. 

Adding CoreMotion to Link Binary with Libraries step in Xcode 4

HelloWorldLayer.h를 열어서 아래 코드를 추가해 맨위에..

#include <CoreMotion/CoreMotion.h>
#import <CoreFoundation/CoreFoundation.h>

다음 변수들도 추가하구

CMMotionManager *motionManager;
CCLabelTTF *yawLabel;
CCLabelTTF *posIn360Label;

property도 정의하고.

@property (nonatomic, retain) CMMotionManager *motionManager;

이제 고기랑 감자를 프로젝트에 가져올 차례야. HelloWorldLayer.m파일을 열러. if((self=[super init])) 구문 내에다 "Hello World" 라벨을 넣는 코드를 제거하고 아래 코드를 넣어.

// add and position the labels
yawLabel = [CCLabelTTF labelWithString:@"Yaw: " fontName:@"Marker Felt" fontSize:12];
posIn360Label = [CCLabelTTF labelWithString:@"360Pos: " fontName:@"Marker Felt" fontSize:12];
yawLabel.position =  ccp(50, 240);
posIn360Label.position =  ccp(50, 300);
[self addChild: yawLabel];
[self addChild:posIn360Label];

폰트정보를 갖는 라벨을 추가했을 뿐이야. 라벨들은 왼쪽에 배치되지.

이제 motion manager를 설정해야 해. 자이로스코프를 시작할거거든.

self.motionManager = [[[CMMotionManager alloc] init] autorelease];
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
if (motionManager.isDeviceMotionAvailable) {
       [motionManager startDeviceMotionUpdates];
}
 
[self scheduleUpdate];

여기서 우리는 motion manager를 할당하고 초기화했어. 업데이트 인터벌도 초당 6회로 했고. 이제 디바이스가 자이로스코프가 가능하다면 업데이트가 시작될거야. 

motion manager의 synthesize로 추가해야 해.

@synthesize motionManager;

업데이트를 스케쥴링하고 있기 때문에 아래와 같이 업데이트메소드를 추가해야 해.

-(void)update:(ccTime)delta {
    CMDeviceMotion *currentDeviceMotion = motionManager.deviceMotion;
    CMAttitude *currentAttitude = currentDeviceMotion.attitude;
 
    // 1: Convert the radians yaw value to degrees then round up/down
    float yaw = roundf((float)(CC_RADIANS_TO_DEGREES(currentAttitude.yaw)));
 
    // 2: Convert the degrees value to float and use Math function to round the value
    [yawLabel setString:[NSString stringWithFormat:@"Yaw: %.0f", yaw]];
 
    // 3: Convert the yaw value to a value in the range of 0 to 360
    int positionIn360 = yaw;
    if (positionIn360 < 0) {
        positionIn360 = 360 + positionIn360;
    }
 
    [posIn360Label setString:[NSString stringWithFormat:@"360Pos: %d", positionIn360]];
 
}

이제 앱을 실행해! Yaw와 positionIn360값의 변화를 볼수 있을거야.

How Did That Work?!

잘 동작하긴 하는데 대체 어케 동작하는건지 궁금할거야. 자 이제 위 코드를 섹션단위로 설명해주께.

Gyroscope app을 다운받아서 실행해바 그러면 아주 멋집 화면을 볼거야.

Free gyroscope app on iTunes App Store

여기서 눈여겨 볼 값은 Yaw값이다! 이 값은 오른쪽에서 왼쪽으로 이동한값이야. 앱에서는 이 값을 각도값으로 표시하지. CC_RADIANS_TO_DEGREES함수를 변환하기 위해 사용하는 예가 되지.

그래서 섹션1에서는 yaw값을 각도값으로 얻고, 각도를 degree로 변환하고, yaw변수로 대입하는 법에 대해 설명하고. 섹션2에서는 화면에 yaw값을 표시할거야. 앱을 실행해보면 각도 값의 범위가 0~180, -180~0인걸 알수 있지.

Gyroscope yaw values displayed on a number line

섹션3을 보면 positionIn360값은 또 머야? 할거야. 자. 이값은 그냥 트릭값인데 화면에 떠있는 물건을 표시하기 위해 사용하게 될거야.

Converting yaw values to 0-360 range


Lights, Camera, Action!

이제 우주선을 추가할차례야. Objective-C class를 하나 추가해 NSObject를 상속하고 EnemyShip.m이란 파일을 생성해.

Replace the contents of EnemyShip.h with:

#import "cocos2d.h"
 
@interface EnemyShip : CCSprite {
    int yawPosition;
    int timeToLive;
}
 
@property (readwrite) int yawPosition;
@property (readwrite) int timeToLive;
 
@end

Replace the contents of EnemyShip.m with:

#import "EnemyShip.h"
 
 
@implementation EnemyShip
 
@synthesize yawPosition, timeToLive;
 
-(id)init {
    self = [super init];
    if (self){ 
        yawPosition = 0;
        timeToLive = 0;
	}
    return self;
}
 
@end

HelloWorldLayer.h를 다시 열고 아래 코드를 추가해

#import "EnemyShip.h"

Inside the interface add:

NSMutableArray *enemySprites;
int enemyCount;
CCSpriteBatchNode *batchNode;

Finally below the interface, add the property for the enemyCount and the definition of methods:

 
@property (readwrite) int enemyCount;
 
-(EnemyShip *)addEnemyShip:(int)shipTag;
-(void)checkEnemyShipPosition:(EnemyShip *)enemyShip withYaw:(float)yawPosition;
-(void)updateEnemyShipPosition:(int)positionIn360 withEnemy:(EnemyShip *)enemyShip;
-(void)runStandardPositionCheck:(int)positionIn360 withDiff:(int)difference withEnemy:(EnemyShip *)enemyShip;

Jump over to the HelloWorldLayer.m file, and make the following modifications to the file:

// Place after the #import statement
#include <stdlib.h>
 
// Place after the other @synthesize statement
@synthesize enemyCount;
#define kXPositionMultiplier 15
#define kTimeToLive 100
 
// Add to the bottom of init
batchNode = [CCSpriteBatchNode batchNodeWithFile:@"Sprites.pvr.ccz"];
[self addChild:batchNode];   
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"Sprites.plist"];

여기서 우리가 튜토리얼 초반에 프로젝트에 추가했던 spritesheet를 로딩해. 다음 우주선을 생성하는 메서드를 추가할거야. 

-(EnemyShip *)addEnemyShip:(int)shipTag {
 
    EnemyShip *enemyShip = [EnemyShip spriteWithSpriteFrameName:@"enemy_spaceship.png"];
 
    // Set position of the space ship randomly
    int x = arc4random() % 360;
    enemyShip.yawPosition = x;   
 
    // Set the position of the space ship off the screen, but in the center of the y axis
    // we will update it in another method
    [enemyShip setPosition:ccp(5000, 160)];
 
    // Set time to live on the space ship
    enemyShip.timeToLive = kTimeToLive;
    enemyShip.visible = true;
 
    [batchNode addChild:enemyShip z:3 tag:shipTag];
 
    return enemyShip;
}

This method accepts an integer value for the tag and returns an EnemyShip CCSprite. The next line of code we are creating an EnemyShip sprite from the spritesheet. Next we are using the arc4random method to get a random integer from 0 to 360. Finally we set the position of the ship, set the timeToLive value to 100, adding the ship to the batch node, and returning the ship.

Below the addEnemyShip method add the following code for the checkEnemyShipPosition method:

-(void)checkEnemyShipPosition:(EnemyShip *)enemyShip withYaw:(float)yawPosition {
    // Convert the yaw value to a value in the range of 0 to 360
    int positionIn360 = yawPosition;
    if (positionIn360 < 0) {
        positionIn360 = 360 + positionIn360;
    }
 
    BOOL checkAlternateRange = false;
 
    // Determine the minimum position for enemy ship
    int rangeMin = positionIn360 - 23;
    if (rangeMin < 0) {
        rangeMin = 360 + rangeMin;
        checkAlternateRange = true;
    }
 
    // Determine the maximum position for the enemy ship
    int rangeMax = positionIn360 + 23;
    if (rangeMax > 360) {
        rangeMax = rangeMax - 360;
        checkAlternateRange = true;
    }    
 
    if (checkAlternateRange) {
        if ((enemyShip.yawPosition < rangeMax || enemyShip.yawPosition > rangeMin ) || (enemyShip.yawPosition > rangeMin || enemyShip.yawPosition < rangeMax)) {
            [self updateEnemyShipPosition:positionIn360 withEnemy:enemyShip];
        }        
    } else {
        if (enemyShip.yawPosition > rangeMin && enemyShip.yawPosition < rangeMax) {
            [self updateEnemyShipPosition:positionIn360 withEnemy:enemyShip];
        } 
    }
}

This method might seem a little bit confusing with the alternate, min, and max ranges. Don’t worry it is pretty simple. First we start out by checking the yaw position of the device (positionIn360) and placing it in the range from 0 to 360 (think full circle).

Gyroscope yaw position visualized on iPhone

Since we have two ends to our number line of 0 to 360, we will need to check to see if the device’s positionIn360 is on either end. We use 23 as an arbitrary number representing the number of degrees that will show on the half of the screen.

Visible degrees on iPhone

So we only need to worry about the ranges from 0 to 23 and 337 to 360 because the other end of the line will need to wrap around.

Lastly we update the position of the enemy space ship if it is in the 46-degree range of the screen. The (checkAlternateRange) if statement is used for determining when to update the position of the enemy spaceship.

If checkAlternateRange is true, then we check to see if the enemy spaceship’s position falls within the min and max range. All of the checks in the first part of this if statement may seem extreme, but if we walk through it using values it makes perfect sense. Let’s assume:

positionIn360 = 20
rangeMin = 357
rangeMax = 20
enemyShip.yawPosition = 359

Because we have to account for both ends of the number line, our min range is greater than the max range. Now we do all of the checks and find out that the enemy ship’s position is greater than rangeMin so we will display the ship on the screen.

The else in that if statement is more straightforward. It just checks to see if the enemy ship’s position is within the min and max range.

What a great segway into the update method! Add the following code below the checkEnemyShipPosition method.

-(void)updateEnemyShipPosition:(int)positionIn360 withEnemy:(EnemyShip *)enemyShip {
    int difference = 0;
    if (positionIn360 < 23) {
        // Run 1
        if (enemyShip.yawPosition > 337) {
            difference = (360 - enemyShip.yawPosition) + positionIn360;
            int xPosition = 240 + (difference * kXPositionMultiplier);
            [enemyShip setPosition:ccp(xPosition, enemyShip.position.y)];
        } else {
            // Run Standard Position Check
            [self runStandardPositionCheck:positionIn360 withDiff:difference withEnemy:enemyShip];
        }
    } else if(positionIn360 > 337) {
        // Run 2
        if (enemyShip.yawPosition < 23) {
            difference = enemyShip.yawPosition + (360 - positionIn360);
            int xPosition = 240 - (difference * kXPositionMultiplier);
            [enemyShip setPosition:ccp(xPosition, enemyShip.position.y)];
        } else {
            // Run Standard Position Check
            [self runStandardPositionCheck:positionIn360 withDiff:difference withEnemy:enemyShip];
        }
    } else {
        // Run Standard Position Check
        [self runStandardPositionCheck:positionIn360 withDiff:difference withEnemy:enemyShip];
    }
}

In this method we are testing to see if the device’s positionIn360 is in one of the three ranges. In the first test we look to see if the positionIn360 is less than 23, if so we want to check to see if there are any enemy ships on the other end of the line (greater than 337).

The second test we look to see if the positionIn360 is greater than 337. If so we want to do the exact opposite of what we just did (check if the enemy ship is less than 23).

The third test (final outer else) we look to we set the position for the enemy ship if it falls between 23 and 337. We are calling the method runStandardPositionCheck. Place the following code below the last method.

-(void)runStandardPositionCheck:(int)positionIn360 withDiff:(int)difference withEnemy:(EnemyShip *)enemyShip {
    if (enemyShip.yawPosition > positionIn360) {
        difference = enemyShip.yawPosition - positionIn360;
        int xPosition = 240 - (difference * kXPositionMultiplier);
        [enemyShip setPosition:ccp(xPosition, enemyShip.position.y)];
    } else {
        difference = positionIn360 - enemyShip.yawPosition;
        int xPosition = 240 + (difference * kXPositionMultiplier);
        [enemyShip setPosition:ccp(xPosition, enemyShip.position.y)];
    }
}

In this method we check to see if the enemyShip position is to the left or right of the device’s positionIn360. When the enemyShip position is less than the positionIn360, it appears on the left side of the screen. When the enemyShip position is greater than the positionIn360 it appears on the right.

Now you say wait a minute! You forgot the difference variable and describing what it does. Okay, here it goes.

If the enemy ship’s yaw position is in the screen’s range (from positionIn360 – 23 to positionIn360 + 23), then first we figure out which side of the screen it is on. If it is greater than the positionIn360 then it goes on the right side of the screen, else it goes on the left.

The difference variable is used to measure the degrees of difference between the device’s positionIn360 and the yaw position of the enemy ship. Once that is known, we multiply the difference by an arbitrary multiplier. This multiplier represents the amount of pixels for each degree. In this case we choose 15.

Based on which side of the screen we will add or subtract this calculated value from 240(screen width divided by 2). And that’s it for the updateEnemyShipPosition method.

Now that all of the required methods are in place we will move on to calling those methods.

At the bottom of the init method, add the following code to add five enemy space ships on the screen.

// Loop through 1 - 5 and add space ships
enemySprites = [[NSMutableArray alloc] init];
for(int i = 0; i < 5; ++i) {
    EnemyShip *enemyShip = [self addEnemyShip:i];
    [enemySprites addObject:enemyShip];
    enemyCount += 1;
}

Since we added the enemy space ships to the screen, we need to make sure their positions update. At the very end of the update method add the following code:

// Loop through array of Space Ships and check the position
for (EnemyShip *enemyShip in enemySprites) {
    [self checkEnemyShipPosition:enemyShip withYaw:yaw];
}

And before we forget, add the following to the bottom of your dealloc method to clean up the enemySpritesArray we created in init:

[enemySprites release];

Now for the moment of truth, go ahead and run your app! You will see 5 space ships at different locations when you rotate the device around.

A simple augmented reality game for the iPhone!

Gratuitous Lasers and Explosions!

So far our augmented reality game is coming along really well, except there’s one major problem: those darn spaceships are getting away scott free!

Obviously we can’t have that, so let’s add some awesome lasers and explosions.

Before we start, let’s get rid of the labels that are on the screen – those were just there for debugging purposes. So search through HelloWorldLayer.m and comment out all matches for yawLabel and posIn360Label. Once you’re done, compile and run and make sure everything still works ok.

Now for the fun part – let’s add some firepower to the game! First we will add a method to check if the player’s firing area hits a space ship. Inside the HelloWorldLayer.h file add the following line of code before @end.

- (BOOL) circle:(CGPoint) circlePoint withRadius:(float) radius collisionWithCircle:(CGPoint) circlePointTwo collisionCircleRadius:(float) radiusTwo;

Moving on to the HelloWorldLayer.m add the method above the dealloc.

- (BOOL) circle:(CGPoint) circlePoint withRadius:(float) radius collisionWithCircle:(CGPoint) circlePointTwo collisionCircleRadius:(float) radiusTwo {
	float xdif = circlePoint.x - circlePointTwo.x;
	float ydif = circlePoint.y - circlePointTwo.y;
 
	float distance = sqrt(xdif*xdif+ydif*ydif);
	if(distance <= radius+radiusTwo) return YES;
 
	return NO;
}

This method is used to check if the radii of two points overlap. The input parameters are for the position of the enemy spaceship and the center of the screen. The radii for both points are set to 50.

First we find the difference between the two points for both x and y. Next we calculate the distance. You may remember this calculation from your studies, it’s called the Pythagorean Theorem. You can read more about this here.

Next we will add a scope to the screen so we can see where our firepower be aimed at. Download theresources for this project, unzip the file, and drag scope.png into your project under the Resources folder. Make sure the “Copy items into destination group’s folder” is checked then click Finish.

Find the init method in HelloWorldLayer.m and add the following code to setup that sprite just before [self scheduleUpdate];

// Add the scope crosshairs
CCSprite *scope = [CCSprite spriteWithFile:@"scope.png"];
scope.position = ccp(240, 160);
[self addChild:scope z:15];
 
// Allow touches with the layer
[self registerWithTouchDispatcher];

If you run the app now, you will see the scope crosshairs in the center of the screen.

A scope added to the augmented reality iPhone game

Great, now let’s add some explosions when the player taps the screen. We will follow the same steps to add Explosion.plist as we did for scope.png. From the resources for the project that you downloaded earlier, drag Explosion.plist into the Resources folder in Xcode, make sure the “Copy items into destination group’s folder” is checked, and click Finish.

You may be wondering what this file is. I used an awesome program to create it, which you may have heard of. It is called Particle Designer, from the good folks of 71 Squared. I will not cover how to create these files, but it is as easy as selecting a type of particle system, making adjustments, and exporting it to a plist.

Now, right before the dealloc method add the following code.

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint location = CGPointMake(240,160);
 
    // 1
    for (EnemyShip *enemyShip in enemySprites) {
        if (enemyShip.timeToLive > 0) {
            // Check to see if yaw position is in range
            BOOL wasTouched = [self circle:location withRadius:50 collisionWithCircle:enemyShip.position collisionCircleRadius:50];
 
            if (wasTouched) {
                enemyShip.timeToLive = 0;
                enemyShip.visible = false;
                enemyCount -= 1;
            }
        }
    }
 
    // 2
    CCParticleSystemQuad *particle = [CCParticleSystemQuad particleWithFile:@"Explosion.plist"];
    particle.position = ccp(240,160);
    [self addChild:particle z:20];
    particle.autoRemoveOnFinish = YES;
 
    // 3
    if (enemyCount == 0) {
        // Show end game
        CGSize winSize = [CCDirector sharedDirector].winSize;
        CCLabelBMFont *label = [CCLabelBMFont labelWithString:@"You win!" fntFile:@"Arial.fnt"];
        label.scale = 2.0;
        label.position = ccp(winSize.width/2, winSize.height/2);
        [self addChild:label z:30];
    }
}

The first section of this code uses the collision detection method we added earlier to check if a space ship is inside of the scope. If one of the space ships was shot, then we will set some properties on the ship to hide it and reduce the enemyCount variable by one. The second section adds the particle system explosion in the center of the screen. The third and final section checks to see if the enemyCount variable equals zero, and if it does, it displays a label to inform the player that the game is over.

The game is a little bit boring at this point in time, so let’s add some very basic AI to change up the position of the space ships after a certain amount of time. At the bottom of the update method add the following code.

// Loop through array of Space Ships and if the timeToLive is zero
    // change the yawPosition of the sprite 
    for (EnemyShip *enemyShip in enemySprites) {
        enemyShip.timeToLive--;
        if (enemyShip.timeToLive == 0) {
            int x = arc4random() % 360;
            [enemyShip setPosition:ccp(5000, 160)];
            enemyShip.yawPosition = x;
            enemyShip.timeToLive = kTimeToLive;
        }
    }

This code will loop through the enemySprites array and update the timeToLive property. Then it will check to see if that property is equal to zero, if it is then it will assign the ship a different random yawPosition and reset the timeToLive. Go ahead and run the game. The game is now much harder to track those space ships down and shoot them!

Pump up the Volume!

Games without audio can seem very boring, so let’s spice things up!

At the top of HellowWorldLayer.m add the import statement for the Simple Audio Engine, which is included with Cocos2D.

#import "SimpleAudioEngine.h"

Scroll down the file and add the following code to the bottom of the init method just before the end of the if ((self=[super init])) statement.

[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"SpaceGame.caf" loop:YES];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"explosion_large.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"laser_ship.caf"];

This will load the background music and preload the effects.

Now, continue scrolling down the file and locate the ccTouchesBegan method. At the top of this method add the following line of code.

[[SimpleAudioEngine sharedEngine] playEffect:@"laser_ship.caf"];

This will play a laser sound effect when the user touches the screen.

Stay inside of the ccTouchesBegan method. In the enemyShip in enemySprites for loop, add the following line inside the (wasTouched) if statement.

[[SimpleAudioEngine sharedEngine] playEffect:@"explosion_large.caf"];

This will play the explosion sound effect when a ship is hit!

Compile and run your code, and enjoy your new tunes!

Where To Go From Here?

Here is the sample project for the augmented reality game we made in the above tutorial.

If you want to learn more about making augmented reality games, here are some great resources to check out:

I hope you had as much fun reading the article as I did creating it! If you have any questions or suggestions for others learning about augmented reality, please join in the forum discussion below!


Posted by 삼스
iOS2012. 6. 14. 15:15



아주간단한 iOS용 증강현실 엔진

http://www.invasivecode.com/blog/archives/1435

BSD license 엔진

https://github.com/sonsongithub/CoreAR

iphone AR 소개

http://www.raywenderlich.com/3997/introduction-to-augmented-reality-on-the-iphone


Posted by 삼스
iOS2012. 3. 24. 13:37


URL Loading System Error Codes

NSURLErrorDomain에서 정의하는 NSError의 에러코드들은 아래와 같다.
enum

{
NSURLErrorUnknown = -1,
NSURLErrorCancelled = -999,
NSURLErrorBadURL = -1000,
NSURLErrorTimedOut = -1001,
NSURLErrorUnsupportedURL = -1002,
NSURLErrorCannotFindHost = -1003,
NSURLErrorCannotConnectToHost = -1004,
NSURLErrorDataLengthExceedsMaximum = -1103,
NSURLErrorNetworkConnectionLost = -1005,
NSURLErrorDNSLookupFailed = -1006,
NSURLErrorHTTPTooManyRedirects = -1007,
NSURLErrorResourceUnavailable = -1008,
NSURLErrorNotConnectedToInternet = -1009,
NSURLErrorRedirectToNonExistentLocation = -1010,
NSURLErrorBadServerResponse = -1011,
NSURLErrorUserCancelledAuthentication = -1012,
NSURLErrorUserAuthenticationRequired = -1013,
NSURLErrorZeroByteResource = -1014,
NSURLErrorCannotDecodeRawData = -1015,
NSURLErrorCannotDecodeContentData = -1016,
NSURLErrorCannotParseResponse = -1017,
NSURLErrorInternationalRoamingOff = -1018,
NSURLErrorCallIsActive = -1019,
NSURLErrorDataNotAllowed = -1020,
NSURLErrorRequestBodyStreamExhausted = -1021,
NSURLErrorFileDoesNotExist = -1100,
NSURLErrorFileIsDirectory = -1101,
NSURLErrorNoPermissionsToReadFile = -1102,
NSURLErrorSecureConnectionFailed = -1200,
NSURLErrorServerCertificateHasBadDate = -1201,
NSURLErrorServerCertificateUntrusted = -1202,
NSURLErrorServerCertificateHasUnknownRoot = -1203,
NSURLErrorServerCertificateNotYetValid = -1204,
NSURLErrorClientCertificateRejected = -1205,
NSURLErrorClientCertificateRequired = -1206,
NSURLErrorCannotLoadFromNetwork = -2000,
NSURLErrorCannotCreateFile = -3000,
NSURLErrorCannotOpenFile = -3001,
NSURLErrorCannotCloseFile = -3002,
NSURLErrorCannotWriteToFile = -3003,
NSURLErrorCannotRemoveFile = -3004,
NSURLErrorCannotMoveFile = -3005,
NSURLErrorDownloadDecodingFailedMidStream = -3006,
NSURLErrorDownloadDecodingFailedToComplete = -3007
}

엄청 많타!@ 


NSURLErrorUnknown

시스템에 정의되지 않은 에러. 이 에러가 나면 프레임웍이나 라이브러리의 문제로 애플에 보고해달란다.Available in Mac OS X v10.2 and later.


NSURLErrorCancelled

로드중에 취소하면 발생
NSURLConnection이나 NSURLDownload는 download가 취소된 경우에는 발생하지 않는다.
Available in Mac OS X v10.2 and later.


NSURLErrorBadURL

잘못된 URL  form으로 접근시도시 발생.
Available in Mac OS X v10.2 and later.


NSURLErrorTimedOut

페이지 로딩이 완료되기 전에 지정한 시간이 지나면 발생.

Available in Mac OS X v10.2 and later.


NSURLErrorUnsupportedURL

URL폼이 프레임웍에서 지원하지 않는 경우, 유효하지 않은 프로토콜입력시 발생 가능함.
Available in Mac OS X v10.2 and later.


NSURLErrorCannotFindHost

URL에서 지정하는  host name을 찾지 못한 경우
Available in Mac OS X v10.2 and later.


NSURLErrorCannotConnectToHost

호스트 연결이 실패한 경우. 호스트이름은 찾았는데 호스트가 다운되어 있거나 해당 포트에 연결 제한이 걸려 연결이 안된 경우에 발생 가능하다.

Available in Mac OS X v10.2 and later.


NSURLErrorDataLengthExceedsMaximum

요청단 데이터가 길이제한을 상회한 경우
Available in Mac OS X v10.5 and later.


NSURLErrorNetworkConnectionLost

서버와의 연결이 로드중에 문제가 발생한 경우

Available in Mac OS X v10.2 and later.


NSURLErrorDNSLookupFailed

See NSURLErrorCannotFindHost

Available in Mac OS X v10.2 and later.


NSURLErrorHTTPTooManyRedirects

redirection이 발생한 경우 또는 16회 이상이 발생한 경우

Available in Mac OS X v10.2 and later.


NSURLErrorResourceUnavailable

요청한 리소스를 찾을 수 없는 경우, 예: "file not found", data decoding error등

Available in Mac OS X v10.2 and later.


NSURLErrorNotConnectedToInternet

네트웍을 요청하였는데 인터넷연결이 안된경우, 자동연결시도가 실패한경우, 연결상태가 안좋은 경우, 또는 사용자가 네트웍연결을 자동으로 선택하지 안은 경우 발생

Available in Mac OS X v10.2 and later.


NSURLErrorRedirectToNonExistentLocation

서버에서 잘못된 redirect를 한경우
Available in Mac OS X v10.2 and later.


NSURLErrorBadServerResponse

서버로부터 잘못된 데이터를 수신한경우. "500 server error"에 대응된다.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorUserCancelledAuthentication

인증과정 중 사용자가 취소한 경우 발생. 

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorUserAuthenticationRequired

인증인 리소스에 접근이 필요할 때 발생
Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorZeroByteResource

Returned when a server reports that a URL has a non-zero content length, but terminates the network connection “gracefully” without sending any data.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorCannotDecodeRawData

Returned when content data received during an NSURLConnection request cannot be decoded for a known content encoding.

Available in Mac OS X v10.5 and later.

Declared in NSURLError.h.

NSURLErrorCannotDecodeContentData

Returned when content data received during an NSURLConnection request has an unknown content encoding.

Available in Mac OS X v10.5 and later.

Declared in NSURLError.h.

NSURLErrorCannotParseResponse

Returned when a response to an NSURLConnection request cannot be parsed.

Available in Mac OS X v10.5 and later.

Declared in NSURLError.h.

NSURLErrorInternationalRoamingOff

Returned when a connection would require activating a data context while roaming, but international roaming is disabled.

Available in Mac OS X v10.7 and later.

Declared in NSURLError.h.

NSURLErrorCallIsActive

Returned when a connection is attempted while a phone call is active on a network that does not support simultaneous phone and data communication (EDGE or GPRS).

Available in Mac OS X v10.7 and later.

Declared in NSURLError.h.

NSURLErrorDataNotAllowed

Returned when the cellular network disallows a connection.

Available in Mac OS X v10.7 and later.

Declared in NSURLError.h.

NSURLErrorRequestBodyStreamExhausted

Returned when a body stream is needed but the client does not provide one. This impacts clients on iOS that send a POST request using a body stream but do not implement the NSURLConnection delegate method connection:needNewBodyStream.

Available in Mac OS X v10.7 and later.

Declared in NSURLError.h.

NSURLErrorFileDoesNotExist

Returned when a file does not exist.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorFileIsDirectory

Returned when a request for an FTP file results in the server responding that the file is not a plain file, but a directory.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorNoPermissionsToReadFile

Returned when a resource cannot be read due to insufficient permissions.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorSecureConnectionFailed

Returned when an attempt to establish a secure connection fails for reasons which cannot be expressed more specifically.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorServerCertificateHasBadDate

Returned when a server certificate has a date which indicates it has expired, or is not yet valid.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorServerCertificateUntrusted

Returned when a server certificate is signed by a root server which is not trusted.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorServerCertificateHasUnknownRoot

Returned when a server certificate is not signed by any root server.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorServerCertificateNotYetValid

Returned when a server certificate is not yet valid.

Available in Mac OS X v10.4 and later.

Declared in NSURLError.h.

NSURLErrorClientCertificateRejected

Returned when a server certificate is rejected.

Available in Mac OS X v10.4 and later.

Declared in NSURLError.h.

NSURLErrorClientCertificateRequired

Returned when a client certificate is required to authenticate an SSL connection during an NSURLConnection request.

Available in Mac OS X v10.6 and later.

Declared in NSURLError.h.

NSURLErrorCannotLoadFromNetwork

Returned when a specific request to load an item only from the cache cannot be satisfied.

This error is sent at the point when the library would go to the network accept for the fact that is has been blocked from doing so by the “load only from cache” directive.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorCannotCreateFile

Returned when NSURLDownload object was unable to create the downloaded file on disk due to a I/O failure.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorCannotOpenFile

Returned when NSURLDownload was unable to open the downloaded file on disk.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorCannotCloseFile

Returned when NSURLDownload was unable to close the downloaded file on disk.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorCannotWriteToFile

Returned when NSURLDownload was unable to write to the downloaded file on disk.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorCannotRemoveFile

Returned when NSURLDownload was unable to remove a downloaded file from disk.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorCannotMoveFile

Returned when NSURLDownload was unable to move a downloaded file on disk.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorDownloadDecodingFailedMidStream

Returned when NSURLDownload failed to decode an encoded file during the download.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

NSURLErrorDownloadDecodingFailedToComplete

Returned when NSURLDownload failed to decode an encoded file after downloading.

Available in Mac OS X v10.2 and later.

Declared in NSURLError.h.

Availability
  • Available in Mac OS X v10.2 with Safari 1.0 installed.
  • Available in Mac OS X v10.2.7 and later.
Declared In
NSURLError.h

Posted by 삼스
iOS2012. 3. 10. 22:13

출처: http://peepleware.com/home/?mid=Tips_dev&page=3&document_srl=12071

아이폰에서 UIWebView 는 PDF 파일외 MS OFFICE계열의 문서 뷰어, 이미지 파일 뷰어, 음악/동영상 파일 열기 등의 다용도 뷰어로 활용할 수 있습니다.


다만 단점이라면 파일 로딩시 파일을 모조리 다 읽어 들여 큰 파일의 경우 메모리 부족 현상이 올 수 있습니다.

그래서 UIWebView로 여러개의 파일들을 지속적으로 반복해서 읽게 되는 경우 메모리 부족으로 인해 UIViewController의 didReceiveMemoryWarning 메소드가 호출될 때가 많아집니다.


그래서 몇 가지 처리를 통해 약간이나마 메모리 부족 현상을 개선해봤습니다.


우선 앱의 초기화 루틴에서 다음과 같이 처리합니다.


- (void)applicationDidBecomeActive:(UIApplication *)application {

    /*

     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

     */


// UIWebView에서 사용될 내부 캐시 영역을 만듭니다. 

// 내부 메모리/디스크를 사용하지 않도록 설정했습니다.

// 설정된 캐시 영역을 공통으로 사용하도록 설정합니다.


// 이 부분의 개선을 통해 더욱 발전시킬 여지가 있습니다.

// 점점 개선한 루틴을 통해 실험해보고, 효과가 있으면 소스를 변경하겠습니다.


NSURLCache *sharedCache = [[NSURLCache allocinitWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]; 

[NSURLCache setSharedURLCache:sharedCache]; 

[sharedCache release];

// 그외 다른 초기 작업들.

}


UIWebView 에서 파일을 열고 사용하다 필요가 없어졌을 때, 호출할 함수.


- (void)unload

{


// 다른 자원들의 해제 작업들.


// UIWebView에서 사용된 요청들의 결과들 캐시를 삭제합니다.

// 이때 대상 캐시는 앱의 초기 구동시에 만들어둔 바로 그 캐시 영역입니다.


NSURLCache *sharedCache = [NSURLCache sharedURLCache]; 

[sharedCache removeAllCachedResponses];

return;

}


그래도 메모리 부족이 발생했을 때 사용할 메소드.


- (void)didReceiveMemoryWarning 

{

    // Releases the view if it doesn't have a superview.

    [super didReceiveMemoryWarning];

    

    // Release any cached data, images, etc. that aren't in use.

NSURLCache *sharedCache = [NSURLCache sharedURLCache]; 

[sharedCache removeAllCachedResponses];

}


우선 이렇게 처리했을 때 메모리 부족 현상이 줄어들었고, Instruments - Allocations 로 메모리 사용 현황을 추적해보니 어느 정도 자원의 해제가 잘 되고 있었습니다.

Posted by 삼스
iOS2012. 3. 10. 02:06


자바와 Objective-C의 Listener pattern의 차이
발췌) Learn Objective-C for Java Developers

Listing 1-2. Observer Pattern in Java and Objective-C

public interface SecurityGateListener

{

    void gateStateChanged( SecurityGate gate );
}
public class SecurityGate
{
    private HashSet listeners;
    private boolean open;
    public void addListener( SecurityGateListener listener )
        {
        listeners.add(listener);
        }
    public void removeListener( SecurityGateListener listener )
        {
        listeners.remove(listener);
        }
    private void fireStateChange( )
        {
        for ( SecurityGateListener listener: listeners )
            listener.gateStateChanged(this);
        }
    public boolean getOpen( )
        {
        return open;
        }
    public void setOpen( boolean open )
        {
        if (this.open!=open) {
            this.open = open;
            fireStateChange();
            }

} }

class SecurityManager implements SecurityGateListener
{
    SecurityGate gate;
    SecurityManager( )
        {
        gate = ...
        gate.addListener(this);
        }
    public void gateStateChanged( SecurityGate gate )
        {
        // security gate changed ...
        }

}

@interface SecurityGate : NSObject {

BOOL open; }

@property BOOL open;
@end
...
@implementation SecurityManager

- (id)init

{
    if ( (self=[super init])!=nil ) {

gate = ...

        [gate addObserver:self forKeyPath:@"open" options:0 context:NULL];
    }
    return self;
}
- (void)observeValueForKeyPath:(NSString*)keyPath
                      ofObject:(id)object
{
    if (object==gate) {
 change:(NSDictionary*)change
context:(void*)context
        // security gate changed...
    }

} @end 

Posted by 삼스
iOS2012. 3. 6. 13:58


NSString *string = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSString *requestString = [[[request URLabsoluteString]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];


Posted by 삼스
iOS2011. 12. 26. 14:10


iOS에서 주소록에 접근하기 위해 제공하는 방안중에 UI를 통한 방법외에 데이터베이스에 직접 접근할 수 있는 방법을 제공한다. 주소록에 직접접근하는 만큼 사용자의 정보를 유의하여 사용해야 한다. 한번 수행한 작업을 되돌릴수는 없기 때문이다.

레코드아이디를 통한 사용법
DB내의 모든 레코드들은 유일한 아이디값을 가진다. 이 값은 항상 동일한 레코드에 대한 참조를 제공하고 해당 레코드가 삭제되거나 MobileMe동기화로 리셋되더라도 유지된다. 쓰래드레벨에서 안전하며 서로 다른 디바이스에 대해서는 보장하지 않는다.
각 레코드에 대한 추천되는 레퍼런스유지 방법은 first, last name을 유지하는 것이다. 추가로 아이디정도를 유지하는것을 추천한다. 검색할 때 레코드아이디로 해당 레코드의 names을 비교하여 다르면 names로 새로 레코드아이디를 얻은 후 아이디를 저장하여 나중에 사용한다.

ABRecordGetRecordID로 레코드 아이디를 얻을 수 있다. 레코드아이디로 persion을 찾으려면 ABAddressBookGetPersonWidthRecordID를 사용한다. 아이디로 그룹을 얻으려면 ABAddressBookGetGroupWithRecordID fmf tkdydgksek. persion을 이름으로 찾으려면 ABAddressBookCopyPeopleWithName을 사용한다.

Persion 레코드 활용하기

ABAddressBookAddRecord와 ABAddressBookRemoveRecord로 주소록 database에서 레코드를 추가 또는 삭제할 수 있다.

주소록 DB에서 person 레코드를 얻는데는 두가지 방법이 있다. ABAddressBookCopyPeopleWithName과 ABAddressBookGetPersonWithRecordID이다. 다른 종류의 검색을 원한다면 ABAddressBookCopyArrayOfAllPeople과 이어서 filteredArrayUsingPredicate메소드를 이용해서 원하는 결과를 얻을 수 있다.

people의 array를 정렬하려면 CFArraySortValues를 ABPersonComparePeopleByName를 비교자로 하고 ABPersonSortOrdering를 context로 사용하면 된다. 

다음은 주소록 DB전체를 정렬하는 예제이다.



Group 레코드로 작업하기

레코디아이디로 특정 그룹을 검색할 수 있다. ABAddressBookGetGroupWithRecordID를 통해서. ABAddressBookCopyArrayOfAllGroups를 통해서 모든 그룹을 array로 검색할 수 도 있다. 또한 전체 그룹의 개수를 ABAddressBookGetGroupCount로 알아낼 수 있다.

그룹의 멤버를 수정할수 있다. 그룹에 persion을 추가하려면 ABGroupAddMember로 하면 되고 제거하려면 ABGroupRemoveMember로 할 수 있다. persion한명이 그룹에 추가되기전에 반드시 주소록 DB에 존재해야 한다. 


 

Posted by 삼스