2. Why Newsstand?
• Contents can be delivered to devices while sleeping
• background downloading
• Good for subscription type business model
• Magazines, Newspaper, Free papers ...
3. How Newsstand Work?
④ Launch with Your Server
Background mode ① Launch Time
Device Token, etc.
⑤ Download Contents
Contents
SSL
② When New Issue is Ready Certificate
Device Token
⑥ Enjoy Reading Contents
③ Push Notification
Apple’s APNS
4. Requirements (Vender)
• Server facility
• Hosting contents for downloading:
• Capable of simultaneous download requests
• Push Notifications
• Server side programming: i.e. Apache+MySQL+PHP
• SSL Certificate *
28. Newsstand Notification
• Receive remote notification only once a day
• You cannot push two contents a day
• You can push regular push notifications multiple time
• For debuging:
[[NSUserDefaults standardUserDefaults] setValue:@YES
forKey:@"NKDontThrottleNewsstandContentNotifications"];
29. Send Token To Your Server
with APS Environment
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token
{
#if DEBUG
! NSString *aps_environment = @"development"; Why?
#else
! NSString *aps_environment = @"production";
#endif
! // send token to your server with other properties aps_environment
}
30. Different Token:
Development/Production
Debug Release
APNS
production
Sandbox
development
app_id token environment
com.electricwoo
0x123...af30 development Your
ds.yourmagazine
com.electricwoo
0x5c6...78c1 production Server APNS
ds.yourmagazine Production
31. Downloading New Issue
Your Server
APNS ① Push Notification ② Query Issues
{ Issue name, Published date, Download URL
"aps":{
! "content-available":1,
}, ③ Download new Issue
...
}
Payload
④ Unzip* and move
⑤ Replace Newsstand Icon
* optional
36. Auto-renewable Subscription
• Newsstand App requires at least one Auto-renewable
subscription or free subscription
• Auto-renewable durations are: 7d, 1m, 2m, 3m, 6m, 1y
• StoreKit won’t let app know duration from product
identifier
• Need to query to your server or hard-coded
37. Restore Problem
• What if Someone purchased auto-renewable
subscriptions in-and-out few times
• Purchased records can be retrieved by restore operation
• But it can be cancelled, and StoreKit wouldn’t tell me...
• Needs to ask to Apple’s server to verify those purchases
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
38. Verifying Receipt
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue
*)queue
! for (SKPaymentTransaction *transaction in queue.transactions) {
! ! NSString *identifier = transaction.payment.productIdentifier;
! ! switch (transaction.transactionState) {
! ! case SKPaymentTransactionStatePurchasing: // ...
! ! case SKPaymentTransactionStateFailed: // ...
! ! case SKPaymentTransactionStatePurchased:
! ! case SKPaymentTransactionStateRestored:
! ! ! [self verifyTransactionReceipt:transaction];
! ! ! break;
! ! }
! }
}
- (void)verifyTransactionReceipt:(SKPaymentTransaction *)transaction
{
... do your stuff ...
[queue finishTransaction:transaction];
}
39. DEBUG
Verifying Receipts
App Store
Production
{
"receipt-data" : "(receipt bytes here)",
"sandbox" : 1
}
{
"status" : 0,
"receipt" : ,
"latest_receipt" : ... {
0 "latest_receipt_info" : ... "receipt-data" : "(receipt bytes here)",
} "password" : "(shared secret bytes here)"
OK }
Sandbox
{
"status" : 0,
App Store
Your Server "receipt" : { (receipt here) },
"latest_receipt" : "(base-64 encoded receipt here
"latest_receipt_info" : { (latest receipt info here
}
40. PRODUCTION
Verifying Receipts
App Store
Production
{
{
"receipt-data" : "(receipt bytes here)",
"receipt-data" : "(receipt bytes here)",
"password" : "(shared secret bytes he
}
}
{
"status" : 21006,
{ "receipt" : { (receipt here) },
"status" : 21006, "latest_receipt" : "(base-64 encoded re
"receipt" : , "latest_receipt_info" : { (latest receip
"latest_receipt" : ... }
21006 "latest_receipt_info" : ...
}
expired
Sandbox
App Store
Your Server
41. Auto renewable subscription
recurring duration
Production Sandbox
1 week 3 minutes
1 month 5 minutes
2 months 10 minutes
3 months 15 minutes
6 months 30 minutes
1 year 1 hour
Automatically expires in 6th time recurring