iOS 6의 StoreKit 변경 내용

iOS 6에서는 앱 내에서 iTunes(및 App Store/iBookstore) 제품을 표시하는 기능과 Apple이 다운로드 가능한 파일을 호스팅하는 새로운 앱 내 구매 옵션이라는 두 가지 변경 사항을 스토어 키트 API에 도입했습니다. 이 문서에서는 Xamarin.iOS를 사용하여 이러한 기능을 구현하는 방법을 설명합니다.

iOS6의 스토어 키트에 대한 기본 변경 내용은 다음과 같은 두 가지 새로운 기능입니다.

  • 앱 내 콘텐츠 표시 및 구매 – 사용자는 앱을 종료하지 않고 앱, 음악, 책 및 기타 iTunes 콘텐츠를 구입하고 다운로드할 수 있습니다. 또한 자신의 앱에 연결하여 구매를 홍보하거나 리뷰와 등급을 장려할 수도 있습니다.
  • 앱에서 구매 호스팅된 콘텐츠 - Apple은 앱에서 구매 제품과 연결된 콘텐츠를 저장하고 제공하므로 별도의 서버에서 파일을 호스트할 필요가 없으며 백그라운드 다운로드를 자동으로 지원하며 코드를 더 적게 작성할 수 있습니다.

StoreKit API에 대한 자세한 내용은 앱 내 구매 가이드를 참조하세요.

요구 사항

이 문서에서 설명하는 스토어 키트 기능에는 Xamarin.iOS 6.0과 함께 iOS 6 및 Xcode 4.5가 필요합니다.

앱 내 콘텐츠 표시 및 구매

iOS의 새로운 앱 내 구매 기능을 사용하면 사용자가 제품 정보를 보고 앱 내에서 제품을 구매하거나 다운로드할 수 있습니다. 이전에는 애플리케이션이 iTunes, App Store 또는 iBookstore를 트리거해야 했기 때문에 사용자가 원래 애플리케이션을 종료하게 됩니다. 이 새 기능은 작업이 완료되면 자동으로 사용자를 앱에 반환합니다.

Automatically returning to an app after purchase

이를 사용하는 방법의 예는 다음과 같습니다.

  • 사용자가 앱을 평가하도록 장려 – 사용자가 앱을 종료하지 않고 평가 및 검토할 수 있도록 App Store 페이지를 열 수 있습니다.
  • 앱 교차 승격 – 사용자가 게시하는 다른 앱을 즉시 구입/다운로드할 수 있도록 허용합니다.
  • 사용자가 콘텐츠를 찾고 다운로드할 수 있도록 지원 – 사용자가 앱에서 찾거나 관리하거나 집계하는 콘텐츠를 구매할 수 있도록 도와줍니다(예: 음악 관련 앱은 노래 재생 목록을 제공하고 앱 내에서 각 노래를 구매할 수 있도록 허용).

SKStoreProductViewController 표시되면 사용자는 iTunes, App Store 또는 iBookstore에 있는 것처럼 제품 정보와 상호 작용할 수 있습니다. 사용자는 다음을 수행할 수 있습니다.

  • 스크린샷 보기(앱용),
  • 샘플 노래 또는 비디오(음악, TV 프로그램 및 영화)
  • 리뷰 읽기(및 쓰기)
  • 보기 컨트롤러 및 스토어 키트 내에서 완전히 발생하는 구매 및 다운로드.

내의 SKStoreProductViewController 일부 옵션은 여전히 사용자가 앱을 떠나 관련 제품 또는 앱의 지원 링크를 클릭하는 등 관련 스토어 앱을 열어야 합니다.

SKStoreProductViewController

모든 앱 내에서 제품을 표시하는 API는 간단합니다. 만들기 및 표시 SKStoreProductViewController만 하면 됩니다. 다음 단계에 따라 제품을 만들고 표시합니다.

  1. StoreProductParameters 생성자에서 매개 변수를 포함하여 뷰 컨트롤러에 매개 변수를 productId 전달하는 개체를 만듭니다.
  2. SKProductViewController를 인스턴스화합니다. 클래스 수준 필드에 할당합니다.
  3. 뷰 컨트롤러를 해제해야 하는 뷰 컨트롤러의 Finished 이벤트에 처리기를 할당합니다. 이 이벤트는 사용자가 취소를 누를 때 호출됩니다. 또는 뷰 컨트롤러 내의 트랜잭션을 종료합니다.
  4. 전달 StoreProductParameters 되는 LoadProduct 메서드와 완료 처리기를 호출합니다. 완료 처리기는 제품 요청이 성공적으로 완료되었음을 검사, 이 경우 모듈식으로 표시 SKProductViewController 해야 합니다. 제품을 검색할 수 없는 경우 적절한 오류 처리를 추가해야 합니다.

예시

문서의 StoreKit 샘플 코드에 있는 ProductView 프로젝트는 제품의 Apple ID를 수락하고 이를 표시하는 메서드를 SKStoreProductViewController구현 Buy 합니다. 다음 코드는 지정된 Apple ID에 대한 제품 정보를 표시합니다.

void Buy (int productId)
{
    var spp = new StoreProductParameters(productId);
    var productViewController = new SKStoreProductViewController ();
    // must set the Finished handler before displaying the view controller
    productViewController.Finished += (sender, err) => {
        // Apple's docs says to use this method to close the view controller
        this.DismissModalViewControllerAnimated (true);
    };
    productViewController.LoadProduct (spp, (ok, err) => { // ASYNC !!!
        if (ok) {
            PresentModalViewController (productViewController, true);
        } else {
            Console.WriteLine (" failed ");
            if (err != null)
                Console.WriteLine (" with error " + err);
        }
    });
}

앱은 실행 중일 때 아래 스크린샷처럼 보입니다. 다운로드 또는 구매는 다음 내에서 SKStoreProductViewController전적으로 발생합니다.

The app looks like this when running

이전 운영 체제 지원

샘플 애플리케이션에는 이전 버전의 iOS에서 App Store, iTunes 또는 iBookstore를 여는 방법을 보여 주는 코드가 포함되어 있습니다. 메서드를 OpenUrl 사용하여 올바르게 만들어진 itunes.com URL을 엽니다.

다음과 같이 버전 검사 구현하여 실행할 코드를 결정할 수 있습니다.

if (UIDevice.CurrentDevice.CheckSystemVersion (6,0)) {
    // do iOS6+ stuff, using SKStoreProductViewController as shown above
} else {
    // don't do stuff requiring iOS 6.0, use the old syntax
    // (which will take the user out of your app)
    var nsurl = new NSUrl("http://itunes.apple.com/us/app/angry-birds/id343200656?mt=8");
    UIApplication.SharedApplication.OpenUrl (nsurl);
}

Errors

사용하는 Apple ID가 올바르지 않으면 다음 오류가 발생합니다. 이는 일종의 네트워크 또는 인증 문제를 의미하기 때문에 혼동될 수 있습니다.

Error Domain=SKErrorDomain Code=5 "Cannot connect to iTunes Store"

설명서 읽기 Objective-C

Apple 개발자 포털의 Store Kit에 대해 읽는 개발자는 이 새로운 기능과 관련하여 설명된 프로토콜인 SKStoreProductViewControllerDelegate 를 볼 수 있습니다. 대리자 프로토콜에는 xamarin.iOS에서 이벤트 SKStoreProductViewControllerFinished 노출된 productViewControllerDidFinish 메서드가 하나만 있습니다.

Apple ID 확인

필요한 SKStoreProductViewController Apple ID는 숫자입니다("com.xamarin.mwc2012"와 같은 번들 ID와 혼동하지 않음). 아래에 나열된 표시하려는 제품의 Apple ID를 확인할 수 있는 몇 가지 방법이 있습니다.

아이튠즈커넥트

게시하는 애플리케이션의 경우 iTunes 커넥트 Apple ID를 쉽게 찾을 수 있습니다.

Finding the Apple ID in iTunes Connect

API 검색

Apple은 App Store, iTunes 및 iBookstore의 모든 제품을 쿼리하는 동적 검색 API를 제공합니다. 검색 API에 액세스하는 방법에 대한 정보는 Apple의 계열사 리소스에서 찾을 수 있지만 API는 등록된 계열사뿐만 아니라 누구에게나 노출됩니다. 결과 JSON을 구문 분석하여 사용할 Apple ID를 검색 trackId 할 수 있습니다 SKStoreProductViewController.

결과에는 앱에서 제품을 렌더링하는 데 사용할 수 있는 표시 정보 및 아트워크 URL을 포함한 다른 메타데이터도 포함됩니다.

다음 몇 가지 예를 참조하세요.

Enterprise 파트너 피드

Apple은 승인된 파트너에게 다운로드 가능한 데이터베이스 준비 플랫 파일의 형태로 모든 제품의 전체 데이터 덤프를 제공합니다. Enterprise 파트너 피드에 액세스할 자격이 있는 경우 해당 데이터 세트에서 모든 제품의 Apple ID를 찾을 수 있습니다.

엔터프라이즈 파트너 피드의 많은 사용자는 제품 판매 시 수수료를 받을 수 있는 계열사 프로그램의 구성원입니다. SKStoreProductViewController 는 (작성 당시) 관련 ID를 지원하지 않습니다.

제품의 Apple ID는 iTunes Preview URL 링크에서 유추할 수 있습니다. 모든 iTunes 제품 링크(앱, 음악 또는 책의 경우)에서 URL id 의 일부를 찾은 다음 번호를 사용합니다.

예를 들어 iBooks에 대한 직접 링크는 다음과 같습니다.

http://itunes.apple.com/us/app/ibooks/id364709193?mt=8

Apple ID가 364709193. 마찬가지로 MWC2012 앱의 경우 직접 링크는

http://itunes.apple.com/us/app/mwc-2012-unofficial/id496963922?mt=8

Apple ID가 496963922.

앱에서 구매 호스트된 콘텐츠

앱에서의 구매가 다운로드 가능한 콘텐츠(예: 책 또는 기타 미디어, 게임 수준 아트 및 구성 또는 기타 큰 파일)로 구성된 경우 이러한 파일은 웹 서버에서 호스트되는 데 사용되었으며, 앱은 구매 후 안전하게 다운로드하기 위해 코드를 통합해야 했습니다. iOS 6부터 Apple은 서버에 파일을 호스트하므로 별도의 서버가 필요하지 않습니다. 이 기능은 소모품이 아닌 제품(소모품 또는 구독이 아님)에만 사용할 수 있습니다. Apple의 호스팅 서비스를 사용할 경우의 이점은 다음과 같습니다.

  • 호스팅 및 대역폭 비용을 절감합니다.
  • 현재 사용 중인 서버 호스트보다 확장성이 더 좋습니다.
  • 서버 쪽 처리를 빌드할 필요가 없으므로 작성할 코드가 줄어듭니다.
  • 백그라운드 다운로드가 구현됩니다.

참고: iOS 시뮬레이터에서 호스팅되는 앱 내 구매 콘텐츠 테스트는 지원되지 않으므로 실제 디바이스로 테스트해야 합니다.

호스트된 콘텐츠 기본 사항

iOS 6 이전에는 제품을 제공하는 두 가지 방법이 있었습니다(Xamarin의 앱 내 구매 설명서에 자세히 설명되어 있음).

  • 기본 제공 제품 – 구매를 통해 '잠금 해제'되지만 애플리케이션에 기본 제공되는 기능(코드 또는 포함된 리소스). 기본 제공 제품의 예로는 잠금 해제된 사진 필터 또는 게임 내 파워업이 있습니다.
  • 서버 배달 제품 – 구매 후 애플리케이션은 사용자가 운영하는 서버에서 콘텐츠를 다운로드해야 합니다. 이 콘텐츠는 구매 중에 다운로드되어 디바이스에 저장된 다음 제품 제공의 일부로 렌더링됩니다. 예를 들어 배경 아트 및 구성 파일로 구성된 책, 잡지 문제 또는 게임 수준이 있습니다.

iOS 6에서 Apple은 서버 제공 제품의 변형을 제공합니다. 이러한 제품은 서버에서 콘텐츠 파일을 호스트합니다. 이렇게 하면 별도의 서버를 운영할 필요가 없으므로 서버 제공 제품을 훨씬 더 간단하게 빌드할 수 있으며 Store Kit는 이전에 직접 작성해야 했던 백그라운드 다운로드 기능을 제공합니다. Apple의 호스팅을 활용하려면 새로운 앱에서 바로 구매 제품에 대한 콘텐츠 호스팅을 사용하도록 설정하고 이를 활용하도록 스토어 키트 코드를 수정합니다. 그런 다음, 제품 콘텐츠 파일은 Xcode를 사용하여 빌드되고 검토 및 릴리스를 위해 Apple의 서버에 업로드됩니다.

The build and deliver process

App Store를 사용하여 호스트된 콘텐츠로 앱 내 구매를 제공하려면 다음 설정 및 구성이 필요합니다.

  • iTunes 커넥트귀하를 대신하여 수집된 자금을 송금할 수 있도록 Apple에 은행 및 세금 정보를 제공해야 합니다. 그런 다음 판매할 제품을 구성하고 샌드박스 사용자 계정을 설정하여 구매를 테스트할 수 있습니다. Apple에서 호스트하려는 소모성이 없는 제품에 대해서도 호스트된 콘텐츠를 구성해야 합니다.
  • iOS 프로비저닝 포털 – 앱에서 바로 구매를 지원하는 모든 애플리케이션과 마찬가지로 번들 식별자를 만들고 앱에 대한 App Store 액세스를 사용하도록 설정합니다.
  • Store Kit – 제품 표시, 제품 구매 및 트랜잭션 복원을 위한 코드를 앱에 추가합니다. iOS 6 스토어 키트에서는 진행률 업데이트와 함께 백그라운드에서 제품 콘텐츠의 다운로드도 관리합니다.
  • 사용자 지정 코드 – 고객이 구매한 것을 추적하고 구매한 제품 또는 서비스를 제공합니다. Apple에서 호스트하는 콘텐츠를 검색하는 것과 같은 SKDownload 새로운 iOS 6 스토어 키트 클래스를 활용합니다.

다음 섹션에서는 이 문서의 샘플 코드를 사용하여 패키지 만들기 및 업로드에서 구매 및 다운로드 프로세스 관리에 이르기까지 호스트된 콘텐츠를 구현하는 방법을 설명합니다.

예제 코드

샘플 프로젝트 HostedNonConsumables (StoreKitiOS6.zip)는 호스트된 콘텐츠를 사용합니다. 이 앱은 Apple 서버에서 호스팅되는 콘텐츠인 두 개의 "책 장"을 판매합니다. 콘텐츠는 텍스트 파일과 이미지로 구성되지만 실제 애플리케이션에서 훨씬 더 복잡한 콘텐츠를 사용할 수 있습니다.

앱은 구매 전, 도중 및 후에 다음과 같이 표시됩니다.

The app looks like this before, during and after a purchase

텍스트 파일과 이미지가 다운로드되어 애플리케이션의 문서 디렉터리에 복사됩니다. 애플리케이션 스토리지에 사용할 수 있는 다양한 디렉터리에 대한 자세한 내용은 파일 시스템 설명서를 참조 하세요.

iTunes Connect

Apple의 콘텐츠 호스팅을 사용할 새 제품을 만들 때 소모성 제품 유형을 선택해야 합니다. 다른 제품 유형은 콘텐츠 호스팅을 지원하지 않습니다. 또한 판매하는 기존 제품에 대해 콘텐츠 호스팅을 사용하도록 설정해서는 안 되며, 새 제품에 대한 콘텐츠 호스팅만 켜야 합니다.

Select the Non-Consumable product type

제품 ID를 입력합니다. 이 ID는 나중에 이 제품의 콘텐츠를 만들 때 필요합니다.

Enter a Product ID

콘텐츠 호스팅은 세부 정보 섹션에서 설정됩니다. 앱 내 구매가 라이브로 전환되기 전에 취소하려는 경우(일부 테스트 콘텐츠를 업로드한 경우에도) Apple 검사box에서 호스트 콘텐츠를 검사 않습니다. 그러나 앱에서의 구매가 라이브로 전환된 후에는 콘텐츠 호스팅을 제거할 수 없습니다.

Hosting content with Apple

콘텐츠 호스팅을 설정하면 제품에서 업로드 대기 상태 입력하고 다음 메시지를 표시합니다.

The product will enter Waiting for Upload status and show this message

콘텐츠 패키지는 Xcode를 사용하여 만들고 보관 도구를 사용하여 업로드해야 합니다. 콘텐츠 패키지를 만들기 위한 지침은 다음 섹션 만들기에서 제공됩니다. PKG 파일.

만들기. PKG 파일

Apple에 업로드하는 콘텐츠 파일은 다음 제한 사항을 충족해야 합니다.

  • 크기가 2GB를 초과할 수 없습니다.
  • 실행 코드(또는 콘텐츠 외부를 가리키는 symlink)를 포함할 수 없습니다.
  • 적절한 형식(.plist 파일 포함)이어야 하며 .pkg 파일 확장명이 있어야 합니다. 이 작업은 Xcode를 사용하여 다음 지침을 따르는 경우 자동으로 수행됩니다.

이러한 제한 사항을 충족하는 한 다양한 파일 및 형식의 파일을 추가할 수 있습니다. 콘텐츠는 애플리케이션에 배달하기 전에 압축되고 코드가 액세스하기 전에 Store Kit에서 압축을 풉니다.

콘텐츠 패키지를 업로드한 후 최신 콘텐츠로 바꿀 수 있습니다. 일반 프로세스를 통해 검토/승인을 위해 새 콘텐츠를 업로드하고 제출해야 합니다. 업데이트된 콘텐츠 패키지의 ContentVersion 필드를 증가하여 더 최신임을 나타냅니다.

Xcode 앱 내 구매 콘텐츠 프로젝트

앱 내 구매 제품에 대한 콘텐츠 패키지를 만들려면 현재 Xcode가 필요합니다. OBJECTIVE-C CODING이 필요하지 않습니다. Xcode에는 파일과 plist만 포함된 이러한 패키지에 대한 새 프로젝트 형식이 있습니다.

샘플 애플리케이션에는 판매용 책 장이 있습니다. 각 장 콘텐츠 패키지에는 다음이 포함됩니다.

  • 텍스트 파일 및
  • 장을 나타내는 이미지입니다.

먼저 메뉴에서 새 파일 프로젝트를 선택하고 앱에서 바로 구매 콘텐츠를 선택합니다.>

Choose In-App Purchase Content

번들 식별자가 이 제품의 iTunes 커넥트 입력한 제품 ID와 일치하게 제품 이름회사 식별자를 입력합니다.

Enter the Name and Identifier

이제 앱 내 구매 콘텐츠 프로젝트가 비어 있습니다. 파일을 마우스 오른쪽 단추로 클릭하고 추가하거나 프로젝트 탐색기로 끌어올 수 있습니다. ContentVersion올바른지 확인합니다(1.0에서 시작해야 하지만 나중에 콘텐츠를 업데이트하도록 선택하는 경우 콘텐츠를 증가시켜야 합니다).

이 스크린샷은 프로젝트에 포함된 콘텐츠 파일과 기본 창에 표시되는 plist 항목이 있는 Xcode를 보여줍니다.

This screenshot shows Xcode with the content files included in the project and the plist entries visible in the main window

모든 콘텐츠 파일을 추가한 후에는 이 프로젝트를 저장하고 나중에 다시 편집하거나 업로드 프로세스를 시작할 수 있습니다.

업로드. PKG 파일

콘텐츠 패키지를 업로드하는 가장 쉬운 방법은 Xcode 보관 도구를 사용하는 것입니다. 메뉴에서 제품 > 보관을 선택하여 시작합니다.

Choose Archiven

그러면 콘텐츠 패키지가 아래와 같이 보관에 표시됩니다. 보관 유형 및 아이콘은 이 줄이 앱에서 바로 구매 콘텐츠 보관이라는 것을 보여줍니다. 실제로 업로드를 수행하지 않고 오류에 대한 콘텐츠 패키지를 검사 확인...을 클릭합니다.

Validate the package

iTunes 커넥트 자격 증명으로 로그인합니다.

Login with your iTunes Connect credentials

올바른 애플리케이션 및 앱 내 구매를 선택하여 이 콘텐츠를 다음과 연결합니다.

Choose the correct application and in-app purchase to associate this content with

다음 스크린샷과 같은 메시지가 표시됩니다.

An example no issues message

이제 비슷한 프로세스를 거치지만 배포클릭하면 실제로 콘텐츠가 업로드됩니다.

Distribute the app

첫 번째 옵션을 선택하여 콘텐츠를 업로드합니다.

Upload the content

다시 로그인합니다.

Login in

콘텐츠를 업로드할 올바른 애플리케이션 및 앱 내 구매 레코드를 선택합니다.

Choose the application and in-app purchase record

파일이 업로드되는 동안 기다립니다.

The content upload dialog

업로드가 완료되면 콘텐츠가 앱 스토어에 제출되었음을 알려주는 메시지가 표시됩니다.

An example successful upload message

작업이 완료되면 iTunes 커넥트 제품 페이지로 돌아가면 패키지 세부 정보가 표시되고 상태 제출할 준비가 됩니다. 제품이 이 상태 있는 경우 샌드박스 환경에서 테스트를 시작할 수 있습니다. 샌드박스에서 테스트를 위해 제품을 '제출'할 필요는 없습니다.

iTunes Connect it will show the package details and be in Ready to Submit status

보관 파일 업로드와 iTunes 커넥트 상태 업데이트하는 데 시간이 걸릴 수 있습니다(예: 몇 분). 별도로 검토를 위해 제품을 제출하거나 애플리케이션 이진 파일과 함께 제출할 수 있습니다. Apple이 공식적으로 승인한 후에만 콘텐츠를 앱에서 구매할 수 있도록 프로덕션 App Store에서 사용할 수 있습니다.

PKG 파일 형식

Xcode 및 보관 도구를 사용하여 호스트된 콘텐츠 패키지를 만들고 업로드하면 패키지 자체의 콘텐츠가 표시되지 않습니다. 샘플 앱용으로 만든 패키지의 파일 및 디렉터리가 아래 스크린샷과 같으며 루트의 plist 파일과 Contents 하위 디렉터리의 제품 파일이 있습니다.

The plist file in the root and the product files in a Contents subdirectory

디바이스의 패키지에서 Contents 파일을 추출하려면 이 정보를 이해해야 하므로 패키지의 디렉터리 구조(특히 하위 디렉터리의 파일 위치)를 확인합니다.

패키지 콘텐츠 업데이트

승인된 후 콘텐츠를 업데이트하는 절차:

  • Xcode에서 앱 내 구매 콘텐츠 프로젝트를 편집합니다.
  • 범프 버전 번호 위로.
  • iTunes 커넥트 다시 업로드합니다. 후속 구매자는 자동으로 최신 버전을 얻을 수 있지만 이미 이전 버전을 가진 사용자는 알림을받지 않습니다.
  • 앱은 사용자에게 알리고 최신 버전의 콘텐츠를 검색하도록 장려할 책임이 있습니다. 또한 앱은 스토어 키트의 복원 기능을 사용하여 새 버전을 다운로드하는 함수를 빌드해야 합니다.
  • 최신 버전이 있는지 확인하려면 앱에 기능을 빌드하여 SKProducts(예: 제품 가격을 검색하는 데 사용되는 동일한 프로세스)를 가져오고 ContentVersion 속성을 비교할 수 있습니다.

구매 개요

이 섹션을 읽기 전에 기존 앱에서 바로 구매 설명서를 검토합니다.

호스트된 콘텐츠가 있는 제품을 구매하고 다운로드할 때 발생하는 이벤트 시퀀스는 다음 다이어그램에 나와 있습니다.

The sequence of events that occurs when a product with hosted content is purchased and download

  1. 호스트된 콘텐츠를 사용하도록 설정된 iTunes 커넥트 새 제품을 만들 수 있습니다. 실제 콘텐츠는 Xcode에서 별도로 생성된 다음(단순히 파일을 폴더로 끌어서 놓는 것처럼) 보관하고 iTunes에 업로드합니다(코딩이 필요하지 않음). 각 제품은 승인을 위해 제출되고, 그 후에는 구매할 수 있게 됩니다. 샘플 코드에서 이러한 제품 ID는 하드 코딩되지만, iTunes 커넥트 새 제품 및 콘텐츠를 제출할 때 업데이트할 수 있도록 사용 가능한 제품 목록을 원격 서버에 저장하는 경우 Apple에서 콘텐츠를 호스팅하는 것이 더 유연합니다.
  2. 사용자가 제품을 구매하면 처리를 위해 트랜잭션이 결제 큐에 배치됩니다.
  3. 스토어 키트는 처리를 위해 iTunes 서버에 구매 요청을 전달합니다.
  4. iTunes 서버에서 트랜잭션이 완료되고(예: 고객에게 요금이 청구됨) 영수증이 앱에 반환되며, 다운로드 가능한지 여부(그리고 있는 경우 파일 크기 및 기타 메타데이터)를 포함한 제품 정보가 첨부됩니다.
  5. 제품을 다운로드할 수 있는 경우 코드가 검사 결제 큐에 있는 콘텐츠 다운로드 요청을 만들어야 합니다. 스토어 키트는 이 요청을 iTunes 서버로 보냅니다.
  6. 서버는 콘텐츠 파일을 Store Kit에 반환하며, 다운로드 진행률과 시간을 다시 반환하는 콜백을 제공하여 코드에 예상을 기본.
  7. 완료되면 캐시 폴더의 파일 위치를 알리고 전달합니다.
  8. 코드는 파일을 복사하고 확인하고 제품을 구매했음을 기억해야 하는 상태를 저장해야 합니다. 이 기회를 통해 새 파일에서 백업 플래그를 올바르게 설정할 수 있습니다(힌트: 서버에서 제공되며 사용자가 편집하지 않은 경우 사용자가 나중에 언제든지 Apple 서버에서 백업을 검색할 수 있으므로 백업을 건너뛰어야 합니다).
  9. FinishTransaction을 호출합니다. 이 단계는 결제 큐에서 트랜잭션을 제거하기 때문에 중요합니다. 캐시 디렉터리에서 콘텐츠를 복사할 때까지 FinishTransaction을 호출하지 않는 것도 중요합니다. FinishTransaction을 호출하면 캐시된 파일이 빠르게 제거될 수 있습니다.

호스트된 콘텐츠 구매 구현

다음 정보는 전체 앱 내 구매 설명서와 함께 읽어야 합니다. 이 문서의 정보는 호스트된 콘텐츠와 이전 구현 간의 차이점에 중점을 둡니다.

클래스

iOS 6에서 호스트된 콘텐츠를 지원하도록 다음 클래스가 추가되거나 변경되었습니다.

  • SKDownload – 진행 중인 다운로드를 나타내는 새 클래스입니다. API는 제품당 둘 이상의 기능을 허용합니다. 그러나 처음에는 하나만 구현되었습니다.
  • SKProduct – 새 속성이 추가됨: Downloadable, 배열ContentVersionContentLengths.
  • SKPaymentTransaction – 새 속성이 추가되었습니다 Downloads. 이 속성은 이 제품이 다운로드할 수 있는 콘텐츠를 호스팅한 경우 개체 컬렉션을 SKDownload 포함합니다.
  • SKPaymentQueue – 새 메서드가 추가됨: StartDownloads. 개체를 SKDownload 사용하여 이 메서드를 호출하여 호스트된 콘텐츠를 가져옵니다. 다운로드는 백그라운드에서 발생할 수 있습니다.
  • SKPaymentTransactionObserver – 새 메서드: UpdateDownloads. Store Kit는 현재 다운로드 작업에 대한 진행률 정보를 사용하여 이 메서드를 호출합니다.

SKDownload 클래스의 세부 정보:

  • 진행률 – 사용자에게 백분율 전체 표시기를 표시하는 데 사용할 수 있는 0-1 사이의 값입니다. 진행률 == 1을 사용하여 다운로드가 완료되었는지 여부를 감지하지 마세요. 상태 == 완료에 대한 검사.
  • TimeRe기본ing – 다운로드 시간 다시 기본 예상(초)입니다. -1은 여전히 추정치를 계산하고 있다는 것을 의미합니다.
  • 상태 – 활성, 대기 중, 완료됨, 실패, 일시 중지됨, 취소됨
  • ContentURL – 디렉터리의 디스크에 콘텐츠가 Cache 배치된 파일 위치입니다. 다운로드가 완료된 후에만 채워집니다.
  • 오류 – 상태가 실패했는지 이 속성을 확인합니다.

샘플 코드의 클래스 간의 상호 작용은 이 다이어그램에 표시됩니다(호스트된 콘텐츠 구매와 관련된 코드는 녹색으로 표시).

Hosted content purchases is shown in green in this diagram

이러한 클래스가 사용된 샘플 코드는 이 섹션의 re기본der에 표시됩니다.

CustomPaymentObserver(SKPaymentTransactionObserver)

기존 재정의를 UpdatedTransactions 다운로드 가능한 콘텐츠에 대한 검사 변경하고 필요한 경우 호출 StartDownloads 합니다.

public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
    foreach (SKPaymentTransaction transaction in transactions) {
        switch (transaction.TransactionState) {
        case SKPaymentTransactionState.Purchased:
            // UPDATED FOR iOS 6
            if (transaction.Downloads != null && transaction.Downloads.Length > 0) {
                // Purchase complete, and it has downloads... so download them!
                SKPaymentQueue.DefaultQueue.StartDownloads (transaction.Downloads);
                // CompleteTransaction() call has moved after downloads complete
            } else {
                // complete the transaction now
                theManager.CompleteTransaction(transaction);
            }
            break;
        case SKPaymentTransactionState.Failed:
            theManager.FailedTransaction(transaction);
            break;
        case SKPaymentTransactionState.Restored:
            // TODO: you must decide how to handle restored transactions.
            // Triggering all the downloads at once is not advisable.
            theManager.RestoreTransaction(transaction);
            break;
        default:
            break;
        }
    }
}

재정의된 새 메서드 UpdatedDownloads 는 다음과 같습니다. Store Kit는 .에서 트리거된 후 StartDownloads 이 메서드를 호출합니다 UpdatedTransactions. 이 메서드는 확정되지 않은 간격으로 여러 번 호출되어 다운로드 진행률을 제공한 다음 다운로드가 완료되면 다시 호출됩니다. 메서드는 개체 배열 SKDownload 을 허용하므로 각 메서드 호출은 큐에서 여러 다운로드의 상태 제공할 수 있습니다. 아래 구현에서와 같이 다운로드 상태 매번 검사 적절한 조치를 취합니다.

// ENTIRELY NEW METHOD IN iOS6
public override void PaymentQueueUpdatedDownloads (SKPaymentQueue queue, SKDownload[] downloads)
{
    Console.WriteLine (" -- PaymentQueueUpdatedDownloads");
    foreach (SKDownload download in downloads) {
        switch (download.DownloadState) {
        case SKDownloadState.Active:
            // TODO: implement a notification to the UI (progress bar or something?)
            Console.WriteLine ("Download progress:" + download.Progress);
            Console.WriteLine ("Time remaining:   " + download.TimeRemaining); // -1 means 'still calculating'
            break;
        case SKDownloadState.Finished:
            Console.WriteLine ("Finished!!!!");
            Console.WriteLine ("Content URL:" + download.ContentUrl);

            // UNPACK HERE! Calls FinishTransaction when it's done
            theManager.SaveDownload (download);

            break;
        case SKDownloadState.Failed:
            Console.WriteLine ("Failed"); // TODO: UI?
            break;
        case SKDownloadState.Cancelled:
            Console.WriteLine ("Canceled"); // TODO: UI?
            break;
        case SKDownloadState.Paused:
        case SKDownloadState.Waiting:
            break;
        default:
            break;
        }
    }
}

InAppPurchaseManager(SKProductsRequestDelegate)

이 클래스에는 각 다운로드가 성공적으로 완료된 후 호출되는 새 메서드 SaveDownload 가 포함되어 있습니다.

호스트된 콘텐츠가 성공적으로 다운로드되고 디렉터리로 압축을 Cache 푼 것입니다. 의 구조체입니다. PKG 파일은 모든 파일을 하위 디렉터리에 저장 Contents 해야 하므로 아래 코드는 하위 디렉터리 내에서 Contents 파일을 추출합니다.

코드는 콘텐츠 패키지의 모든 파일을 반복하고 디렉터리에 ProductIdentifier복사 Documents 합니다. 마지막으로 결제 큐에서 트랜잭션을 제거하기 위해 호출하는 호출 FinishTransaction 을 호출CompleteTransaction합니다.

// ENTIRELY NEW METHOD IN iOS 6
public void SaveDownload (SKDownload download)
{
    var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); // Documents folder
    var targetfolder = System.IO.Path.Combine (documentsPath, download.Transaction.Payment.ProductIdentifier);
    // targetfolder will be "/Documents/com.xamarin.storekitdoc.montouchimages/" or something like that
    if (!System.IO.Directory.Exists (targetfolder))
        System.IO.Directory.CreateDirectory (targetfolder);
    foreach (var file in System.IO.Directory.EnumerateFiles
             (System.IO.Path.Combine(download.ContentUrl.Path, "Contents"))) { // Contents directory is the default in .PKG files
        var fileName = file.Substring (file.LastIndexOf ("/") + 1);
        var newFilePath = System.IO.Path.Combine(targetfolder, fileName);
        if (!System.IO.File.Exists(newFilePath)) // HACK: this won't support new versions...
            System.IO.File.Copy (file, newFilePath);
        else
            Console.WriteLine ("already exists " + newFilePath);
    }
    CompleteTransaction (download.Transaction); // so it gets 'finished'
}

FinishTransaction 호출되면 다운로드한 파일이 더 이상 Cache 디렉터리에 있지 않습니다. 를 호출 FinishTransaction하기 전에 모든 파일을 복사해야 합니다.

기타 고려 사항

위의 예제 코드는 호스트된 콘텐츠 구매의 매우 간단한 구현을 보여 줍니다. 고려해야 할 몇 가지 추가 사항이 있습니다.

업데이트된 콘텐츠 검색

호스트된 콘텐츠 패키지를 업데이트할 수 있지만 스토어 키트는 이미 제품을 다운로드하고 구매한 사용자에게 이러한 업데이트를 푸시하는 메커니즘을 제공하지 않습니다. 이 기능을 구현하려면 코드가 DownloadableSKProduct.ContentVersion 속성(있는 경우SKProduct)을 정기적으로 검사 값이 증가했는지 감지할 수 있습니다. 또는 푸시 알림 시스템을 빌드할 수 있습니다.

업데이트된 콘텐츠 버전 설치

위의 샘플 코드는 파일이 이미 있는 경우 파일 복사를 건너뜁니다. 다운로드 중인 콘텐츠의 최신 버전을 지원하려는 경우에는 좋지 않습니다.

또는 버전을 위해 명명된 폴더에 콘텐츠를 복사하고 현재 버전(예: NSUserDefaults 완료된 구매 레코드를 저장하는 위치)을 추적하는 것이 좋습니다.

트랜잭션 복원

SKPaymentQueue.DefaultQueue.RestoreCompletedTransactions 호출되면 Store Kit는 사용자의 모든 이전 트랜잭션을 반환합니다. 많은 수의 항목을 구매했거나 각 구매에 큰 콘텐츠 패키지가 있는 경우 모든 항목이 한 번에 다운로드 대기함에 따라 복원으로 인해 많은 네트워크 트래픽이 발생할 수 있습니다.

관련 콘텐츠 패키지의 실제 다운로드와 별도로 제품을 구입했는지 여부를 추적하는 것이 좋습니다.

다운로드 일시 중지, 다시 시작 및 취소

샘플 코드는 이 기능을 보여주지 않지만 호스트된 콘텐츠 다운로드를 일시 중지하고 다시 시작할 수 있습니다. 및 SKPaymentQueue.DefaultQueue 에 대한 PauseDownloadsResumeDownloads 메서드가 있습니다CancelDownloads.

다운로드 전에 코드가 결제 큐에서 호출 FinishTransaction 되면 Finished 해당 다운로드가 자동으로 취소됩니다.

다운로드한 콘텐츠에서 SKIP-Backup 플래그 설정

Apple의 iCloud 백업 지침에 따르면 서버에서 쉽게 복원되는 비 사용자 콘텐츠는 백업되지 않아야 합니다(iCloud 스토리지를 불필요하게 사용하기 때문). 백업 특성을 설정하는 방법에 대한 자세한 내용은 파일 시스템 설명서를 참조하세요.

요약

이 문서에서는 iOS6의 스토어 키트의 두 가지 새로운 기능인 앱 내에서 iTunes 및 기타 콘텐츠를 구매하고 Apple 서버를 활용하여 앱에서 바로 구매를 호스트하는 두 가지 새로운 기능을 소개했습니다. 이 소개는 스토어 키트 기능 구현에 대한 전체 적용 범위를 위해 기존 앱에서 바로 구매 설명서 와 함께 읽어야 합니다.