of 238 /238
These are confidential sessions—please refrain from streaming, blogging, or taking pictures Session 302 Daniel Feldman Engineering Manager, Mac App Store Selling Products with Store Kit

Session 302 - Selling Products with Store Kit.pdf

Embed Size (px)

DESCRIPTION

Session 302 - Selling Products with Store Kit.pdf

Text of Session 302 - Selling Products with Store Kit.pdf

  • These are confidential sessionsplease refrain from streaming, blogging, or taking pictures

    Session 302Daniel FeldmanEngineering Manager, Mac App Store

    Selling Products with Store Kit

  • 75%Of the 25 top grossing

    iPhone apps use In-App Purchase

  • Todays Agenda

    Selling Store Content Using In-App Purchase In Detail: The Purchase Queue App Store Hosted Content Best Practices

  • Todays Agenda

    Selling Store Content Using In-App Purchase In Detail: The Purchase Queue App Store Hosted Content Best Practices

  • Selling Store Products

  • Selling Store Products

    Look up item identifier

  • Selling Store Products

    Look up item identifier Search API

  • Selling Store Products

    Look up item identifier Search API Enterprise Partner Feed

  • Selling Store Products

    Look up item identifier Search API Enterprise Partner Feed Parse iTunes Preview URLs

  • Selling Store Products

    Look up item identifier Search API Enterprise Partner Feed Parse iTunes Preview URLs

    Configure a SKStoreProductViewController

  • Selling Store Products

    Look up item identifier Search API Enterprise Partner Feed Parse iTunes Preview URLs

    Configure a SKStoreProductViewController Tell the view controller to load

  • Selling Store Products

    Look up item identifier Search API Enterprise Partner Feed Parse iTunes Preview URLs

    Configure a SKStoreProductViewController Tell the view controller to load Show the view controller

  • How to Sell a Store Product

  • - (void)showProductViewController:(UIButton *)sender {

    }

    - (void)showProductViewController:(UIButton *)sender {

    }

    How to Sell a Store Product

  • - (void)showProductViewController:(UIButton *)sender {

    }

    - (void)showProductViewController:(UIButton *)sender {

    }

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    How to Sell a Store Product

  • - (void)showProductViewController:(UIButton *)sender {

    }

    - (void)showProductViewController:(UIButton *)sender {

    }

    viewController.delegate = self;

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    How to Sell a Store Product

  • - (void)showProductViewController:(UIButton *)sender {

    }

    - (void)showProductViewController:(UIButton *)sender {

    }

    NSDictionary *parameters = @{SKStoreProductParameterITunesItemIdentifier: [NSNumber numberWithInteger: itemIdentifier]};

    NSDictionary *parameters = @{SKStoreProductParameterITunesItemIdentifier: [NSNumber numberWithInteger: itemIdentifier]};

    viewController.delegate = self;viewController.delegate = self;

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    How to Sell a Store Product

  • - (void)showProductViewController:(UIButton *)sender {

    NSDictionary *parameters = @{SKStoreProductParameterITunesItemIdentifier: [NSNumber numberWithInteger: itemIdentifier]};

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    viewController.delegate = self;

    }

    How to Sell a Store Product

  • - (void)showProductViewController:(UIButton *)sender {

    NSDictionary *parameters = @{SKStoreProductParameterITunesItemIdentifier: [NSNumber numberWithInteger: itemIdentifier]};

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    viewController.delegate = self;

    }

    How to Sell a Store Product

  • - (void)showProductViewController:(UIButton *)sender {

    NSDictionary *parameters = @{SKStoreProductParameterITunesItemIdentifier: [NSNumber numberWithInteger: itemIdentifier]};

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    vCtrl.delegate = self;

    }

    How to Sell a Store Product

  • [viewController loadProductWithParameters:parameters completionBlock: ^(BOOL result, NSError *error) {

    }]

    - (void)showProductViewController:(UIButton *)sender {

    NSDictionary *parameters = @{SKStoreProductParameterITunesItemIdentifier: [NSNumber numberWithInteger: itemIdentifier]};

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    vCtrl.delegate = self;

    }

    How to Sell a Store Product

  • [viewController loadProductWithParameters:parameters completionBlock: ^(BOOL result, NSError *error) {

    }]

    [viewController loadProductWithParameters:parameters completionBlock: ^(BOOL result, NSError *error) {

    }]

    if (result)

    [[self.window rootViewController] presentModalViewController:viewController animated:YES];

    - (void)showProductViewController:(UIButton *)sender {

    NSDictionary *parameters = @{SKStoreProductParameterITunesItemIdentifier: [NSNumber numberWithInteger: itemIdentifier]};

    SKStoreProductViewController *viewController = [[SKStoreProductViewController alloc] init];

    vCtrl.delegate = self;

    }

    How to Sell a Store Product

  • How to Sell a Store Product

    - (void)productViewControllerDidFinish:

    (SKStoreProductViewController *)viewController

  • Todays Agenda

    Selling Store Content Using In-App Purchase In Detail: The Purchase Queue App Store Hosted Content Best Practices

  • In-App Purchase Types

  • In-App Purchase Types

    Consumable

  • In-App Purchase Types

    Consumable Non-consumable

  • In-App Purchase Types

    Consumable Non-consumable Auto-renewing subscription

  • In-App Purchase Types

    Consumable Non-consumable Auto-renewing subscription Non-renewing subscription

  • In-App Process Overview

  • In-App Process Overview

    Set Up Content

    VerifyPurchases

    PurchaseProcess

  • In-App Process Overview

    Set Up Content

    VerifyPurchases

    PurchaseProcess

    In Xcode/iTunes Connect

  • In-App Process Overview

    Set Up Content

    VerifyPurchases

    PurchaseProcess

    On DeviceIn Xcode/iTunes Connect

  • In-App Process Overview

    Set Up Content

    VerifyPurchases

    PurchaseProcess

    On DeviceIn Xcode/iTunes Connect On Mac/Server

  • In-App Process Overview

    PurchaseProcess

  • In-App Process Overview

  • In-App Process Overview

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • From within your appNSArray* productIdentifiers = @[@"com.myCompany.myApp.product1",

    @"com.myCompany.myApp.product2",

    @"com.myCompany.myApp.product3"];

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • From within your appNSArray* productIdentifiers = @[@"com.myCompany.myApp.product1",

    @"com.myCompany.myApp.product2",

    @"com.myCompany.myApp.product3"];

    From your server Develop your own client/server communication

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

    NSArray* productIdentifiers = @[@"com.myCompany.myApp.product1",

    @"com.myCompany.myApp.product2",

    @"com.myCompany.myApp.product3"];

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

    NSArray* productIdentifiers = @[@"com.myCompany.myApp.product1",

    @"com.myCompany.myApp.product2",

    @"com.myCompany.myApp.product3"];

    NSSet* identifierSet = [NSSet setWithArray:productIdentifiers];

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

    NSArray* productIdentifiers = @[@"com.myCompany.myApp.product1",

    @"com.myCompany.myApp.product2",

    @"com.myCompany.myApp.product3"];

    SKProductsRequest* request = [[SKProductsRequest alloc]

    initWithProductIdentifiers: identifierSet];

    NSSet* identifierSet = [NSSet setWithArray:productIdentifiers];

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

    NSArray* productIdentifiers = @[@"com.myCompany.myApp.product1",

    @"com.myCompany.myApp.product2",

    @"com.myCompany.myApp.product3"];

    SKProductsRequest* request = [[SKProductsRequest alloc]

    initWithProductIdentifiers: identifierSet];

    request.delegate = self;

    [request start];

    NSSet* identifierSet = [NSSet setWithArray:productIdentifiers];

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:

    (SKProductsResponse *)response

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:

    (SKProductsResponse *)response

    response.products: description, name, price

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:

    (SKProductsResponse *)response

    response.products: description, name, price

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

    response.invalidProductIdentifiers

  • - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:

    (SKProductsResponse *)response

    response.products: description, name, price

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

    response.invalidProductIdentifiers

    - (void)request:(SKRequest *)request didFailWithError:(NSError *)error

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • Your responsibility

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • Your responsibility Make it fit your app

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • Your responsibility Make it fit your app Dont just show, sell!

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • SKPayment *payment = [SKPayment paymentWithProduct:product];

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • SKPayment *payment = [SKPayment paymentWithProduct:product]; [[SKPaymentQueue defaultQueue] addPayment:payment];

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

    RegisterObserver

    Add an observer at launch [[SKPaymentQueue defaultQueue] addTransactionObserver: self];

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

    RegisterObserver

    Add an observer at launch [[SKPaymentQueue defaultQueue] addTransactionObserver: self];

    Implement SKPaymentTransactionObserver protocol- (void)paymentQueue:(SKPaymentQueue *)queue

    updatedTransactions:(NSArray *)transactions

  • - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    RegisterObserver

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • switch(transaction.transactionState) {

    }

    for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • switch(transaction.transactionState) {

    }

    for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    case SKPaymentTransactionStatePurchased:

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • switch(transaction.transactionState) {

    }

    for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    case SKPaymentTransactionStatePurchased:

    case SKPaymentTransactionStateFailed:

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • Unlock functionality in your app

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • Unlock functionality in your app Download additional content from your server

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

  • Restoring Transactions

  • Restoring Transactions

    A way to get all In-App purchases back

  • Restoring Transactions

    A way to get all In-App purchases back Important for app re-downloads, multi-device scenarios

  • Restoring Transactions

    A way to get all In-App purchases back Important for app re-downloads, multi-device scenarios Applications must offer this

  • Restoring Transactions

    A way to get all In-App purchases back Important for app re-downloads, multi-device scenarios Applications must offer this Only non-consumable and auto-renew subscription types

  • Restoring Transactions

    A way to get all In-App purchases back Important for app re-downloads, multi-device scenarios Applications must offer this Only non-consumable and auto-renew subscription types Dont auto-restore on launch

  • Make AssetAvailable

    ProcessTransaction

    FinishTransaction

  • StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

  • StartRestore

    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

  • StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

  • StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

    for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

  • StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

    switch(transaction.transactionState) {

    }

    for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

  • StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

    switch(transaction.transactionState) {

    }

    for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    case SKPaymentTransactionStateRestored:

  • StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

  • Unlock functionality in your app

    StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

  • Unlock functionality in your app Download additional content from your server

    StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

  • StartRestore

    Make AssetAvailable

    ProcessTransaction

    FinishTransaction

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

  • The Sandbox Environment

  • The Sandbox Environment

    Production

  • The Sandbox Environment

    SandboxProduction

  • The Sandbox Environment

    SandboxProduction

  • The Sandbox Environment

    SandboxProduction

  • The Sandbox Environment

    SandboxProduction

  • The Sandbox Environment

    [Environment: Sandbox]

  • HowThe Sandbox Environment

  • HowThe Sandbox Environment

    Setup in iTunes Connect

  • HowThe Sandbox Environment

    Setup in iTunes Connect Create a test user

  • HowThe Sandbox Environment

    Setup in iTunes Connect Create a test user Enter products for sale

  • HowThe Sandbox Environment

    Setup in iTunes Connect Create a test user Enter products for sale

    Build and sign

  • HowThe Sandbox Environment

    Setup in iTunes Connect Create a test user Enter products for sale

    Build and sign Mac: Fetch a receipt

  • HowThe Sandbox Environment

    Setup in iTunes Connect Create a test user Enter products for sale

    Build and sign Mac: Fetch a receipt Buy a product!

  • Todays Agenda

    Selling Store Content Using In-App Purchase In Detail: The Purchase Queue App Store Hosted Content Best Practices

  • Your app

    SKPaymentQueue

  • StoreKitYour app

    SKPaymentQueue

  • StoreKitYour app

    SKPaymentQueue

    SKPaymentQueue

  • StoreKitYour app

    SKPaymentQueue

    SKPaymentQueueObserver

    SKPaymentQueue

  • StoreKitYour app

    SKPaymentQueue

    iTunes Store

    SKPaymentQueueObserver

    SKPaymentQueue

  • StoreKitYour app

    SKPaymentQueue

    iTunes Store

    SKPaymentQueueObserver

    SKPaymentQueue

    SKPayment

  • StoreKitYour app

    SKPaymentQueue

    iTunes Store

    SKPaymentQueueObserver

    SKPaymentQueue

    SKPayment

  • StoreKitYour app

    SKPaymentQueue

    iTunes Store

    SKPaymentQueueObserver

    SKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKit

    SKPaymentQueueObserver

    Your app

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKit

    SKPaymentQueueObserver

    Your app

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKit

    SKPaymentQueueObserver

    Your app

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKit

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKit

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKitYour App

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKitYour App

    SKPaymentQueueObserver

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • StoreKitYour App

    SKPaymentQueueObserver

    SKPaymentQueue

    iTunes StoreSKPaymentQueue

    SKTransaction

    SKPayment

  • Todays Agenda

    Selling Store Content Using In-App Purchase In Detail: The Purchase Queue App Store Hosted Content Best Practices

  • The App Store will now host yourIn-App content for you!

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • The App Store will now host yourIn-App content for you!

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • App Store Hosted Content

  • App Store Hosted Content

    Dont need to host your own content

  • App Store Hosted Content

    Dont need to host your own content Save time, money, and bugs

  • App Store Hosted Content

    Dont need to host your own content Save time, money, and bugs Scalable and reliable

  • App Store Hosted Content

    Dont need to host your own content Save time, money, and bugs Scalable and reliable

    Easy API

  • App Store Hosted Content

    Dont need to host your own content Save time, money, and bugs Scalable and reliable

    Easy API Save development time

  • App Store Hosted Content

    Dont need to host your own content Save time, money, and bugs Scalable and reliable

    Easy API Save development time Comes with a security model

  • App Store Hosted Content

    Dont need to host your own content Save time, money, and bugs Scalable and reliable

    Easy API Save development time Comes with a security model Take advantage of background downloads

  • App Store Hosted Content

  • App Store Hosted Content

    No additional cost to use this

  • App Store Hosted Content

    No additional cost to use this Limit of 2GB

  • App Store Hosted Content

    No additional cost to use this Limit of 2GB They go through review

  • App Store Hosted Content

    No additional cost to use this Limit of 2GB They go through review No code

  • App Store Hosted Content

    No additional cost to use this Limit of 2GB They go through review No code Same content rules as apps

  • WorkflowApp Store Hosted Content

  • WorkflowApp Store Hosted Content

    Build and test your content

  • WorkflowApp Store Hosted Content

    Build and test your content Upload your content to iTunes Connect

  • WorkflowApp Store Hosted Content

    Build and test your content Upload your content to iTunes Connect App Store will host that content

  • WorkflowApp Store Hosted Content

    Build and test your content Upload your content to iTunes Connect App Store will host that content Use new Store Kit API to download content

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • No Change

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • SKProduct has new properties

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • SKProduct has new properties BOOL downloadable;

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • SKProduct has new properties BOOL downloadable; NSString* contentVersion;

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • SKProduct has new properties BOOL downloadable; NSString* contentVersion; NSArray* contentLengths;

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • No Change

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • No Change

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    ProcessTransaction

    Load In-AppIdentifiers

    FinishTransaction

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

    if(transaction.downloads)

  • for(SKPaymentTransaction* transaction in transactions){

    }

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    [[SKPaymentQueue defaultQueue] startDownloads:

    transaction.downloads];

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

    if(transaction.downloads)

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • - (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:

    (NSArray *)downloads;

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • SKDownload

  • SKDownload

    download.progress

    download.timeRemaining

    download.state

    download.error

    download.contentURL

    0.128

    213 (seconds)

    SKDownloadStateActiveSKDownloadStateWaitingSKDownloadStateFinishedSKDownloadStateFailedSKDownloadStatePausedSKDownloadStateCancelled

    NSError

    file:// URL

  • SKDownload

    download.progress

    download.timeRemaining

    download.state

    download.error

    download.contentURL

    0.128

    213 (seconds)

    SKDownloadStateActiveSKDownloadStateWaitingSKDownloadStateFinishedSKDownloadStateFailedSKDownloadStatePausedSKDownloadStateCancelled

    NSError

    file:// URL

  • SKDownload

    download.progress

    download.timeRemaining

    download.state

    download.error

    download.contentURL

    0.128

    213 (seconds)

    SKDownloadStateActiveSKDownloadStateWaitingSKDownloadStateFinishedSKDownloadStateFailedSKDownloadStatePausedSKDownloadStateCancelled

    NSError

    file:// URL

  • SKDownload

    download.progress

    download.timeRemaining

    download.state

    download.error

    download.contentURL

    0.128

    213 (seconds)

    SKDownloadStateActiveSKDownloadStateWaitingSKDownloadStateFinishedSKDownloadStateFailedSKDownloadStatePausedSKDownloadStateCancelled

    NSError

    file:// URL

  • SKDownload

    download.progress

    download.timeRemaining

    download.state

    download.error

    download.contentURL

    0.128

    213 (seconds)

    SKDownloadStateActiveSKDownloadStateWaitingSKDownloadStateFinishedSKDownloadStateFailedSKDownloadStatePausedSKDownloadStateCancelled

    NSError

    file:// URL

  • Showing progress

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • Showing progress- (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:

    (NSArray *)downloads;

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • Showing progress- (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:

    (NSArray *)downloads;

    download.progress

    download.timeRemaining

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • Showing progress- (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:

    (NSArray *)downloads;

    download.progress

    download.timeRemaining

    download.state

    download.error

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • Pausing and resuming

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

    - (void) pauseDownloads:(NSArray *)downloads;- (void) resumeDownloads:(NSArray *)downloads;- (void) cancelDownloads:(NSArray *)downloads;

    SKPaymentQueue

  • Accessing the content

    download.contentURL

    When SKDownload is in the SKDownloadStateFinished state:

    ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

  • ProcessTransaction

    ShowIn-App UI

    Make Asset Available

    FetchProduct Info

    MakePurchase

    Load In-AppIdentifiers

    FinishTransaction

    No Change

  • Restoring App Store Hosted Content

  • Restoring App Store Hosted Content

    Just like non-hosted content

  • Restoring App Store Hosted Content

    Just like non-hosted content Check for transaction.downloads

  • Restoring App Store Hosted Content

    Just like non-hosted content Check for transaction.downloads Downloading is your decision

  • Restoring App Store Hosted Content

    Just like non-hosted content Check for transaction.downloads Downloading is your decision

    Always call finishTransaction:

  • What form does it take?App Store Hosted Content

  • What form does it take?App Store Hosted Content

    A folder with any data you need

  • What form does it take?App Store Hosted Content

    A folder with any data you needContentInfo.plist at root level

  • What form does it take?App Store Hosted Content

    A folder with any data you needContentInfo.plist at root levelContentVersion

  • What form does it take?App Store Hosted Content

    A folder with any data you needContentInfo.plist at root levelContentVersionIAPProductIdentifier

  • What form does it take?App Store Hosted Content

    A folder with any data you needContentInfo.plist at root levelContentVersionIAPProductIdentifier

    Other data in Contents subfolder

  • What form does it take?App Store Hosted Content

    / ContentInfo.plist Contents/ PieceOfContent1.mov PieceOfContent2.mov

  • Where does it get installed?App Store Hosted Content

    On iOS

  • Where does it get installed?App Store Hosted Content

    On iOS

    Purgeable Stays Local Backed Up

    Caches

    Documents

    Documents (with backup flag set)

  • Where does it get installed?App Store Hosted Content

    On iOS

    Purgeable Stays Local Backed Up

    Caches

    Documents

    Documents (with backup flag set)

  • Where does it get installed?App Store Hosted Content

    On iOS

    Purgeable Stays Local Backed Up

    Caches

    Documents

    Documents (with backup flag set)

  • Where does it get installed?App Store Hosted Content

  • Where does it get installed?App Store Hosted Content

    On OS X

  • Where does it get installed?App Store Hosted Content

    On OS X Special Application Support folder

  • Where does it get installed?App Store Hosted Content

    On OS X Special Application Support folder Use API to access it

  • Where does it get installed?App Store Hosted Content

    On OS X Special Application Support folder Use API to access it

    + (NSURL *) contentURLForProductID:(NSString *)productID;

  • Where does it get installed?App Store Hosted Content

    On OS X Special Application Support folder Use API to access it

    + (NSURL *) contentURLForProductID:(NSString *)productID;

    + (void) deleteContentForProductID:(NSString *)productID;

  • Updating contentApp Store Hosted Content

  • Updating contentApp Store Hosted Content

    Edit your content

  • Updating contentApp Store Hosted Content

    Edit your content Update version in ContentInfo.plist

  • Updating contentApp Store Hosted Content

    Edit your content Update version in ContentInfo.plist Re-upload to iTunes Connect

  • Updating contentApp Store Hosted Content

    Edit your content Update version in ContentInfo.plist Re-upload to iTunes Connect Requires restore to get new content

  • Updating contentApp Store Hosted Content

    Edit your content Update version in ContentInfo.plist Re-upload to iTunes Connect Requires restore to get new content To determine if something has changed

  • Updating contentApp Store Hosted Content

    Edit your content Update version in ContentInfo.plist Re-upload to iTunes Connect Requires restore to get new content To determine if something has changed

    Fetch SKProducts

  • Updating contentApp Store Hosted Content

    Edit your content Update version in ContentInfo.plist Re-upload to iTunes Connect Requires restore to get new content To determine if something has changed

    Fetch SKProducts Compare to ContentInfo.plist

  • Transitioning from self-hosted contentApp Store Hosted Content

  • Transitioning from self-hosted contentApp Store Hosted Content

    Must be added as new products in iTunes Connect

  • Demo

  • Todays Agenda

    Selling Store Content Using In-App Purchase In Detail: The Purchase Queue App Store Hosted Content Best Practices

  • Best Practices

  • Best Practices

    Check queue on launch

  • Best Practices

    Check queue on launch Call finishTransaction:

  • Best Practices

    Check queue on launch Call finishTransaction: Restoring purchases is required

  • Best Practices

    Check queue on launch Call finishTransaction: Restoring purchases is required iOS: Move out of ~/Caches if you want it to persist

  • Best Practices

    Check queue on launch Call finishTransaction: Restoring purchases is required iOS: Move out of ~/Caches if you want it to persist Test in sandbox before deploying

  • More Information

    Paul MarcosApplication Services [email protected]

    DocumentationIn-App Purchase Programming Guide and Validating App Store Receiptshttp://developer.apple.com

    Search API and Enterprise Partner Feedhttp://www.apple.com/itunes/affiliates

    Apple Developer Forumshttp://devforums.apple.com

  • What's New in iTunes Connect for App Developers Nob HillThursday 9:00AM

    Building Great Newsstand Apps Nob HillThursday 2:00PM

    Managing Subscriptions with In-App Purchase MissionThursday 3:15PM

    Related Sessions

  • In-App Purchase Lab App Services Lab AWednesday 3:15PM

    iTunes Connect for App Developers Lab App Services Lab AThursday 11:30AM

    In-App Purchase Lab App Services Lab BThursday 4:30PM

    Newsstand Lab App Services Lab AFriday 9:00AM

    App Store Lab App Store Lab (Level 3)Monday-Friday 9:00AM

    Labs

  • The last 3 slides after the logo are intentionally left blank for all presentations.

  • The last 3 slides after the logo are intentionally left blank for all presentations.

  • The last 3 slides after the logo are intentionally left blank for all presentations.