OpenGL, iOS 의 대가.. Jeff Lamarche. SceneKit ..

바로가기는 여기   외국사람인데, kr ??  암튼..

씬 킷은 현재까지는 맥앱에만 해당되는 기술인데 되게 좋더라..

개념적으로 뭘 하느냐.

OpenGL 위에, 앱킷 같은 상위 레벨 아래에 위치함. 씬킷 뷰는 완전히 ‘레이어-감지’ 하여 코어 애니메이션으로 애니메이션 가능하다.
뷰 자체가 아니마 가능할 뿐더러, 뷰의 상수를 아니마 할 수 있음.

씬 킷은 주로 ‘scene graph management’ 라이브러리로 알려진 것이다. 이놈은 하나 이상의 3차원객체와 광원, 카메라를 매니지한다. 이 아이템들이 합쳐져서 스크린에 보여진다. 씬킷은 마야, 모도, 블레더 등으로부터 콜라다 형식으로 데이터를 받을 수 있다. 컬라다는 3차원 객체 외에 광원, 카메라, 애니매이션 정보까지 포함한다.

씬킷은 앱킷과 잘 어우러져 NSView 에 이미 있는 힛 테스트를 통해 터치, 마우스 클릭 등의 프로젝션 등을 다룰 수 있다.

씬킷에서 모든 렌더링이 편하게 가능하며 필요할 때는 렌더 딜리깃을 통해 직접 제어가능하다. 편하게 구현 가능하면서 세세한 조정도 가능하다는 얘기.
이것을 보면 얼마나 이 프레임 워크에 공이 들어갔는지 알 수 있다.

결론적으로 씬킷은 어려운 걸 쉽제 해준다. 하지만, 아직 문서도 완전하지 않고….

셋업

Xcode 4.4 or 4.5 ..  산사자 필요…

ARC 를 켜라.

쿼츠코어 추가.

씬뷰 추가

파일 추가..  닙파일… 씬뷰 객체를 윈도우에 드래그..  레이아웃 할 필요 없다…  블라블라.. HTFSceneView 로 명명해라.

헤더에  씬킷.h 추가..  이제 컴파일 가능.

씬 배경 색 지정

간단한 씬 만들기

씬을 코드로 만들어보자.  씬킷에 대한 기본 툴과 용어를 익힐 것이다.

기본은 카메라, 광원, 객체이다. 이것 없이는 별볼일 없다.

빈 SCNScene 객체 생성. 이 객체를 갖으면 씬에 아이템을 추가하기 위해서 “노드”라 불리는 객체를 생성한다. SCNNode 클래스로 대표되는 노드는 다른 종류의 객체를 붙들어 매기 위해 만들어졌다. 위계가 있어 자식, 부모 관계 로 붙일 수 있다.

모든 씬은 ‘루트 노드’ 가 있고 rootNode 로 불리며 씬의 톱 위상의 객체를 붙인다. 노드를 만들고 거기에 카메라, 3차원객체 등을 붙고 그 노드를 루트노드 혹은 그 자식에 붙여서 씬에 객체를 추가한다. 꽤 직관적이지 않은가?

한번 붙이면 리무브 할 때까지 남아있는다.  awakeFromNib 에 코드를 붙이자.

씬 만들기

// Create an empty scene
SCNScene *scene = [SCNScene scene];
self.scene = scene;

카메라 추가.

// Create a camera
SCNCamera *camera = [SCNCamera camera];
camera.xFov = 45; // Degrees, not radians
camera.yFov = 45;
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = camera;
cameraNode.position = SCNVector3Make(0, 0, 30);
[scene.rootNode addChildNode:cameraNode];

카메라에 라디언 대신 ‘도’ 로 표시. 카메라 클래스를 보면 오픈쥐엘 뷰포트와 유사하다는 것을 알 것이다. 우연이 아니고. 씬킷의 ‘카메라’는 GL 뷰포트 … 이 다가 아니다. ?? 카메라가 {0, 0, 30} 에 있으면 카메라의 위치에 따라 렌더하기 전에 씬의 모든 노드는 Z 방향으로 -30 물러날 것이다. 카메라는 회전가능. 씬은 카메라의 시점으로 렌더 된다.

이제 객체. 빌트인 객체를 제공. 실린더, 큐브, 공, 콘, 평면, 튜브, 토러스, 피라미드, 텍스트.. SCNGeometry 에서 상속.  생성한 후 속성 부여, 노드에 할당, 노드를 씬에 추가.. 예제.

// Create a torus
SCNTorus *torus = [SCNTorus torusWithRingRadius:8 pipeRadius:3];
SCNNode *torusNode = [SCNNode nodeWithGeometry:torus];
CATransform3D rot = CATransform3DMakeRotation(MCP_DEGREES_TO_RADIANS(45), 1, 0, 0);
torusNode.transform = rot;
[scene.rootNode addChildNode:torusNode];

Transform3D .. 매트릭스.. GLKMatrix4 와 유사. 위치, 스케일, 회전 등에 대한 정보를 담는다.

다음은 조명. 지금 상태에서 프로그램을 돌리면, 토러스가 그려지지만 완전한 평면 흰색일 것임.

OpenGL from the ground.. 를 상기한다면 3디 그래픽의 기본은 디퓨즈, 앰비언트, 스펙큘러 .. 설명..

스펙큘러 : 밝은 점.. 스팟.. 직광..
앰비언트 광원 : 분명한 소스가 없는 광원.. 여러곳에서 반사된 광원. 세이드 부분.. 어두운 곳..
디퓨즈 : 밝은 부분 ?? 아마도..

씬킷의 라이팅은 더 진보된 것. 씬킷에서 스펙큘러 하이라잇은 광원 세팅보다는 재료 로 부터 온다. 나중에 살펴보자. 하지만 디퓨즈와 앰비언트는 씬에 빛을 추가함으로 얻을수 있다.

씬킷에서 광원은 여러가지 타잎. 앰비언트. 직광.

앰비언트 추가해보자. 일반적으로 하나의 앰비언트 광원. 더 드라마틱한 경우 없을 수도 있음.  앰비언트의 위치와 변위는 상관없음.

// Create ambient light
SCNLight *ambientLight = [SCNLight light];
SCNNode *ambientLightNode = [SCNNode node];
ambientLight.type = SCNLightTypeAmbient;
ambientLight.color = [NSColor colorWithDeviceWhite:0.1 alpha:1.0];
ambientLightNode.light = ambientLight;
[scene.rootNode addChildNode:ambientLightNode];

// Create a diffuse light
SCNLight *diffuseLight = [SCNLight light];
SCNNode *diffuseLightNode = [SCNNode node];
diffuseLight.type = SCNLightTypeOmni;
diffuseLightNode.light = diffuseLight;
diffuseLightNode.position = SCNVector3Make(-30, 30, 50);
[scene.rootNode addChildNode:diffuseLightNode];

 

// Create a torus

iTunes Connect Developer Guide [ In-App Purchase ] section

원문

IAP 의 관리는 App Summary 페이지의 Manage In-App Purchases  버튼을 클릭하여 이루어짐. 이 버튼은 계정이 어드민, 기술 역할 등에 할당되었을 때 ‘보여진다’

About In-App Purchase

스토어-킷 을 통해 구현한다. 스토어-킷은 당신의 앱을 대신하여 앱 스토어에 연결하고, 결재를 위한 UI 제공,  ..

>> 추가적인 성능
>> 북 리더앱의 새 책.
>> 게임의 뉴 레벨
>> 온라인 게임에서의 가상 특성 구입
>> turn-by-turn 맵 서비스 접속
>> 전자 잡지 / 뉴스레터

앱내구매를 앱에서 구현하려면 ‘최신 Paid Applications contract’ 가 유효하고, 팀 요원이 프로그램 라이센스에 동의해야 함.
애플에 리뷰를 위해 보내기전에, 모든 앱내구매는 ‘아이튠즈 커넥트’ 에 등록되고 샌드박스 환경에서 테스트 되어야 한다.

Registering In-App Purchases

무료/유료 앱에 적용 가능.  제품은 먼저 ‘아 – 커넥트’에 등록되어야 함. 등록 시 ‘이름, 설명, 가격’ 와 다른 메타 데이터 추가.
제품은 ‘product indentifier’ 라는 유니크한 문자로 구별함. 앱이 스토어킷을 사용 시 이 ‘구별자’ 를 사용.
당신은 앱내구매를  ‘생성, 수정, 삭제’ 할 수 있고 리뷰를 위해 애플에 제출할 수 있다.
앱내 구매에는 10,000 개 까지 다른 ‘구별자’를 생성할 수 있다. 이것은 거래 숫자가 아님.
앱 서머리 페이지에서 생성 시작할 수 있다.

Creating In-App Purchases

>> Log into iTunes Connect
>> Manage Your Applications
>> Click the App
>> Manage IAP click  (이 버튼이 보이지 않으면 계약에 동의하지 않은 것임)
>> Create New
>> Select Type .. consumable, Non-consumable, Auto-Renewable Subscriptions, Free Subscription, Non-renewing subscription
>> Fill out the form
>> Click Save.  앱내 구매가 ‘관리’ 페이지에서 보인다.

Entering In-App Purchase Information

표 12-2 의 내용 입력.

>> Free Subscription form [ 언어 추가, 스크린 샷 … ]

>> Non-Renewable Subscription or Consumable form..

Table 12-2 Common IAP properties
Reference Name, Product ID < unique UTF-8 alphanumerical identifier > Not editable, Pricing and Availability, Languages, Review Notes < for Apple review >, Screenshot

Privacy Policy URL input…

Testing Your IAP

샌드박스 환경 -> 금융 결재 발생 안함.  앱 스토어를 이요하지만 결재 하지는 않음. 실제 결제와 동일한 값 리턴.  앱내구매에 한정된 특별한 ‘아-커넥트’ 계정 사용.  일반 계정은 샌드박스에서 쓸 수 없음.

Creating Test User Accounts

커넥트를 이용하여 1개 이상의 테스트 계정 생성. 각 언어에 대하여 1개 이상의 계정 생성해야. 테스트 유저 계정은 새롭고, 유니크한 애플 계정이어야하고, 기존 계정을 이용할 수 없다.
어드민, 기술 역할로 어사인 되어 있어야 생성 가능. ‘커넥트’ 에 접근 불가, 하지만 앱내구매에서 테스트 가능. 개발 환경의 등록된 테스트 기기에서만..

>> Log into iTunes Connect.
>> Manage Users..
>> Click Test User.
>> Add New User.

<<주의>> 실수로 테스트 유저 계정으로  (테스트 환경 대신) 기기에서 제품 환경에  로그인하면, 테스트 계정은 invalid 되고 다시 사용할 수 없게 됨.

Using Test User Accounts

#1. 테스트 유저 계정 셋업. 아이디(이메일), 비번 입력.
#2. 테스트 기기의 계정 정보 초기화 할것. 테스팅 중에 실제 계정이 쓰일 염려때문.
<< 주의 >> 테스트 계정 정보를 ‘스토어 세팅’ 패널에서 넣지 말것. 이것은 테스트 계정을 폐기할 수 있음.
#3. 샌드박스에 대비한( against ) 기능을 테스트하려면 기기를 개발 웤스테이션에 연결하고 기기를 Active SDK 로 선택할 것.
#4. 앱이 스토어킷 API 를 통해 결재를 요청할 때, 결재 확인 창이 뜨고 Sign In 패널이 또 뜬다. ‘Use Existing Account’ 선택하고 테스트 유저네임과 비번을 넣은 후 구매 테스트를 완료함. 금융거래는 일어나지 않지만 영수증을 포함한 완전한 구매가 생성. 테스트 계정에는 신용카드정보가 없으므로 실제 금융 거래는 일어나지 않음.

Sandbox Testing Your IAP

애플에 리뷰를 위해 제출하기 전에 샌드박스 환경에서 테스트 해야 함. 샌드박스로 테스트 하기 전에 아이튠즈 계정에서 로그 아웃 해야 함. 테스트 유저 계정을 테스트 디바이스에서 로그인 하면 계정이 폐기된다.
오토-리뉴어블 앱내구매를 테스팅할 때는 지속 시간이 짧아진다. 부가적으로 샌드박스 제출은 6번 까지만 ‘오토-리뉴’ 된다.

Submitting Your In-App Purchases

새로 만든 ‘앱내구매’를 다음 바이너리 업로드 때 써밋 할 지, 지금 바로 리뷰에 들어갈 지 결정해야 한다.
첫번째 앱내구매는 앱 버전과 같이 제출되어야 한다. Version Details 페이지에 해야 한다. (적어야 한다) 바이너리가 업로드 되고, 첫번째 앱내구매가 리뷰에 들어간 후 추가적인 앱내구매는 앰내구매 ‘관리’ 뷰의 테이블을 통해 제출될 수 있다.
바이너리와 함께 서밋하려면 Version Details Page 에서 선택해야 한다.
스크린 샷에서 에디트 를 클릭하여 어느 놈이 리뷰되야 하는지 선택한다.
세이브. 바이너리와 함께 제출되었다.
대규모 제출도 가능.  제출할 놈을 체크.. Ready to Submit 으로 만든다.   “Submit for Review” 클릭..
<개별 제출> 앱내구매 페이지에서 개별적으로 제출 가능. “Ready to Submit” 에서 “Waiting for Review” 로 바뀌고 즉시 리뷰를 위해 보내진다.

Tracking Your IAP Status

제출한 후에는 “Waiting for Review” 로 상태가 바뀐다. 리뷰를 기다리는 동안 수정이 가능하다.

“In Review” 로 바뀜. 수정 불가.이 상태에서는 삭제도 불가.

“Approved” 바이너리 없이 …. 암튼 완료..

바이너리와 함께 제출하기로 선택했다면, 애플에서 심사 후에 앱 심사가 끝날 때까지 approved 가 안 나옴.
리뷰 과정에서 앱내구매가 리젝되면 애플에서 연락이 간다.  커넥트의 Contact Us 를 통해 물어볼 수 있다. 리젝되면 다시 만들어야 한다.

Why Objective-C Metaprogramming Dramatically Improves Your iOS App

출처 : http://kurtedelbrock.com/objective-c-metaprogramming/

1. Domain Specific Languages (dynamic method naming)

tap 키워드로 블락 이용.. ??

2. Validation

???

3. Templates

클래스 이름을 스트링으로 하여 관련 클래스를 동적으로 생성.

4. Mocking

유닛 테스트 시 함수를 안 만들고 간단히 리턴하는 형태로 대신할 때.

 

 

IAP (2) Making a purchase

Making a Purchase

Collecting Payment

결재를 위해 어플이 payment object 생성하여 페이먼트 큐에 ‘큐’ 한다. 그림 3-1 참조.
서버에서 paymentQueue:updatedTransaction 을 받음..
Payment 가 생성되면 persistent transaction 생성하여 갖고 있음. 지불한 후에 transaction 이 업데이트 되고 어플에서 이것을 반영하는 옵서버 구현.   옵저버는 사용자에게 구매한 아이템 제공하고 큐에서 transaction제거.

SKPayment

결재는 payment object 에서 시작.  PI와 수량 포함. 같은 객체를 한번 이상 ‘큐’ 가능. 각각은 다른 결재로 인식.
유저는 세팅에서 구매를 비활성 시킬 수 있다. 구매를 큐하기 전에, 어플은 구매가 진행될 수 있는지 확인해야 함.  [paymentQueueu :: canMakePayment] 메서드를 통해.

SKPaymentQueue

앱 스토어와 통신하는 객체. [payment]가 큐에 추가되면 스토어킷은 앱 스토어에 요청 전송. 스토어킷이 사용자가 결재를 확인하는 대화상자 제공. 완성된 결재는 옵서버에 리턴함.

SKPaymentTransaction

구매 시 생성. 어플이 transaction 의 상태를 결정하도록 하는 속성을 갖고 있다. 결재가 성공하면 성공에 관한 디테일 정보를 담는다. 큐에 지연된 액션을 물어볼 수 있지만, 옵서버가 기다리는 게 일반적.

SKPaymentTransactionObserver 프로토콜

어플이 구현하여 옵서버에 등록. 옵서버의 주된 임무는 완성된 액션을 검사하고 구매한 아이템을 유저에게 전달하며 큐에서 제거.
사용자가 아이템 구매를 시도할 때까지 기다리기 보다,  어플 런칭 시 큐와 옵서버와 연결되어 있어야 한다. 어플이 끝날 때 트랜잭션은 잃지 않음. 다음에 런칭할 때 스토어 킷은 트랜잭션 재개.  어플 초기화 시 옵저버 추가는 모든 트랜잭션이 어플에 돌아왔는 지 확인한다.

Restoring Transactions

액션이 진행되서 큐에서 제거되면 다시 볼 수 없다. 하지만, 어플이 결과를 저장해야 할 속성이 있으면 그 인터페이스를 구현해야 한다. 이 인터페이스는 다른 기기에 제품을 추가할 수 있으며, 기기가 지워지면, 원 기기에서 거래를 복구할 수 있다.
스토어킷은 비-소비성 제품, 오토-리뉴어블 구독,  프리-구독 에 대해 빌트-인 복구 기능 지원.
트랜잭션을 복구하려면 당신 어플은 큐의 restoreCompleltedTransactions 메서드 콜. 큐는 앱 스토어에 복구위한 요청을 보냄. 앱스토어는 새로운 트랜잭션 복구를 생성. 복구 트랜잭션 객체의 originalTransaction은 원래의 정보를 담고 있다.  어플에서는 이것을 통해 구매한 아이템을 풀어준다.  스토어킷이 복구를 마친 후 큐 옵서버에 paymentQueueRestoreCompletedTransactionsFinished: 메서드를 보낸다.

유저가 복구가능한 아이템을 구매하려고 하면  (당신이 구현한 복구 인터페이스 대신) 보통 트랜잭션을 받는다. 하지만, 유저는 같은 아이템에 대해 다시 과금 받지는 않는다. 당신 어플은 이 액션을 원래 액션과 똑같이 취급해야 한다.

넌-리뉴잉 구독, 소비성 제품은 복구되지 않는다. 하지만, 넌-리뉴잉은 복구되야 한다. 이것은 당신 서버에서 알아서 해라.