Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for downloading content hosted by Apple #343

Merged
merged 8 commits into from
Jan 31, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions SwiftyStoreKit-iOS-Demo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

completeIAPTransactions()

SwiftyStoreKit.updatedDownloadsHandler = { downloads in

let finishedDownloadsCount = downloads.filter { $0.downloadState == .finished }.count
if finishedDownloadsCount == downloads.count {
SwiftyStoreKit.finishTransaction(downloads[0].transaction)
}
}

return true
}
Expand Down
7 changes: 5 additions & 2 deletions SwiftyStoreKit-iOS-Demo/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ class ViewController: UIViewController {
SwiftyStoreKit.purchaseProduct(appBundleId + "." + purchase.rawValue, atomically: atomically) { result in
NetworkActivityIndicatorManager.networkOperationFinished()

if case .success(let purchase) = result {
if case .success(let purchase, let downloads) = result {
if !downloads.isEmpty {
SwiftyStoreKit.start(downloads)
}
// Deliver content from server, then:
if purchase.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(purchase.transaction)
Expand Down Expand Up @@ -267,7 +270,7 @@ extension ViewController {
// swiftlint:disable cyclomatic_complexity
func alertForPurchaseResult(_ result: PurchaseResult) -> UIAlertController? {
switch result {
case .success(let purchase):
case .success(let purchase, _):
print("Purchase Success: \(purchase.productId)")
return nil
case .error(let error):
Expand Down
24 changes: 22 additions & 2 deletions SwiftyStoreKit/PaymentQueueController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protocol TransactionController {
}

public enum TransactionResult {
case purchased(purchase: PurchaseDetails)
case purchased(purchase: PurchaseDetails, downloads: [SKDownload])
case restored(purchase: Purchase)
case failed(error: SKError)
}
Expand All @@ -47,7 +47,12 @@ public protocol PaymentQueue: class {
func remove(_ observer: SKPaymentTransactionObserver)

func add(_ payment: SKPayment)


func start(_ downloads: [SKDownload])
func pause(_ downloads: [SKDownload])
func resume(_ downloads: [SKDownload])
func cancel(_ downloads: [SKDownload])

func restoreCompletedTransactions(withApplicationUsername username: String?)

func finishTransaction(_ transaction: SKPaymentTransaction)
Expand Down Expand Up @@ -151,7 +156,21 @@ class PaymentQueueController: NSObject, SKPaymentTransactionObserver {
paymentQueue.finishTransaction(skTransaction)
}

func start(_ downloads: [SKDownload]) {
paymentQueue.start(downloads)
}
func pause(_ downloads: [SKDownload]) {
paymentQueue.pause(downloads)
}
func resume(_ downloads: [SKDownload]) {
paymentQueue.resume(downloads)
}
func cancel(_ downloads: [SKDownload]) {
paymentQueue.cancel(downloads)
}

var shouldAddStorePaymentHandler: ShouldAddStorePaymentHandler?
var updatedDownloadsHandler: UpdatedDownloadsHandler?

// MARK: SKPaymentTransactionObserver
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
Expand Down Expand Up @@ -210,6 +229,7 @@ class PaymentQueueController: NSObject, SKPaymentTransactionObserver {

func paymentQueue(_ queue: SKPaymentQueue, updatedDownloads downloads: [SKDownload]) {

updatedDownloadsHandler?(downloads)
}

func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion SwiftyStoreKit/PaymentsController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class PaymentsController: TransactionController {
if transactionState == .purchased {
let purchase = PurchaseDetails(productId: transactionProductIdentifier, quantity: transaction.payment.quantity, product: payment.product, transaction: transaction, originalTransaction: transaction.original, needsFinishTransaction: !payment.atomically)

payment.callback(.purchased(purchase: purchase))
payment.callback(.purchased(purchase: purchase, downloads: transaction.downloads))

if payment.atomically {
paymentQueue.finishTransaction(transaction)
Expand Down
3 changes: 2 additions & 1 deletion SwiftyStoreKit/SwiftyStoreKit+Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public struct RetrieveResults {

// Purchase result
public enum PurchaseResult {
case success(purchase: PurchaseDetails)
case success(purchase: PurchaseDetails, downloads: [SKDownload])
case error(error: SKError)
}

Expand All @@ -80,6 +80,7 @@ public struct RestoreResults {
}

public typealias ShouldAddStorePaymentHandler = (_ payment: SKPayment, _ product: SKProduct) -> Bool
public typealias UpdatedDownloadsHandler = (_ downloads: [SKDownload]) -> Void

// MARK: Receipt verification

Expand Down
28 changes: 25 additions & 3 deletions SwiftyStoreKit/SwiftyStoreKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ public class SwiftyStoreKit {

private func processPurchaseResult(_ result: TransactionResult) -> PurchaseResult {
switch result {
case .purchased(let purchase):
return .success(purchase: purchase)
case .purchased(let purchase, let downloads):
return .success(purchase: purchase, downloads: downloads)
case .failed(let error):
return .error(error: error)
case .restored(let purchase):
Expand All @@ -109,7 +109,7 @@ public class SwiftyStoreKit {
var restoreFailedPurchases: [(SKError, String?)] = []
for result in results {
switch result {
case .purchased(let purchase):
case .purchased(let purchase, _):
let error = storeInternalError(description: "Cannot purchase product \(purchase.productId) from restore purchases path")
restoreFailedPurchases.append((error, purchase.productId))
case .failed(let error):
Expand Down Expand Up @@ -216,6 +216,28 @@ extension SwiftyStoreKit {
sharedInstance.paymentQueueController.shouldAddStorePaymentHandler = shouldAddStorePaymentHandler
}
}

/**
* Register a handler for paymentQueue(_:updatedDownloads:)
*/
public static var updatedDownloadsHandler: UpdatedDownloadsHandler? {
didSet {
sharedInstance.paymentQueueController.updatedDownloadsHandler = updatedDownloadsHandler
}
}

public class func start(_ downloads: [SKDownload]) {
sharedInstance.paymentQueueController.start(downloads)
}
public class func pause(_ downloads: [SKDownload]) {
sharedInstance.paymentQueueController.pause(downloads)
}
public class func resume(_ downloads: [SKDownload]) {
sharedInstance.paymentQueueController.resume(downloads)
}
public class func cancel(_ downloads: [SKDownload]) {
sharedInstance.paymentQueueController.cancel(downloads)
}
}

extension SwiftyStoreKit {
Expand Down