Date post: | 03-Jan-2016 |
Category: |
Documents |
Upload: | foufoutos73 |
View: | 54 times |
Download: | 1 times |
These are confidential sessions—please refrain from streaming, blogging, or taking pictures
Session 302Daniel FeldmanEngineering Manager, Mac App Store
Selling Products with Store Kit
Today’s Agenda
• Selling Store Content• Using In-App Purchase • In Detail: The Purchase Queue • App Store Hosted Content• Best Practices
Today’s Agenda
• Selling Store Content• Using In-App Purchase • In Detail: The Purchase Queue • App Store Hosted Content• Best Practices
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
- (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
Today’s Agenda
• Selling Store Content• Using In-App Purchase • In Detail: The Purchase Queue • App Store Hosted Content• Best Practices
In-App Purchase Types
• Consumable• Non-consumable• Auto-renewing subscription• Non-renewing subscription
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
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• Don’t 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
• 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• Don’t auto-restore on launch
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:
…
• 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];
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!
Today’s Agenda
• Selling Store Content• Using In-App Purchase • In Detail: The Purchase Queue • App Store Hosted Content• Best Practices
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
StoreKitYour App
SKPaymentQueueObserver
SKPaymentQueue
iTunes StoreSKPaymentQueue
SKTransaction
SKPayment
StoreKitYour App
SKPaymentQueueObserver
SKPaymentQueue
iTunes StoreSKPaymentQueue
SKTransaction
SKPayment
Today’s 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
• Don’t need to host your own content■ Save time, money, and bugs■ Scalable and reliable
App Store Hosted Content
• Don’t need to host your own content■ Save time, money, and bugs■ Scalable and reliable
• Easy API
App Store Hosted Content
• Don’t need to host your own content■ Save time, money, and bugs■ Scalable and reliable
• Easy API■ Save development time
App Store Hosted Content
• Don’t 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
• Don’t 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
• 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
• 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
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
• 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
• 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
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
• 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
• 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
• Must be added as new products in iTunes Connect
Today’s Agenda
• Selling Store Content• Using In-App Purchase • In Detail: The Purchase Queue • App Store Hosted Content• Best Practices
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