I'm building the In App Purchases part of my app using StoreKit and am facing a strange behaviour while purchasing and downloading content hosted by Apple.
This is the code in a nutshell:
SKPaymentQueue.default().add(delegate)
...
SKPaymentQueue.default().add(payment)
Delegate
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
transactions.forEach { transaction in
switch transaction.transactionState {
case .purchased, .restored:
if transaction.downloads.isEmpty {
SKPaymentQueue.default().finishTransaction(transaction)
didPurchaseProduct(nil)
} else {
SKPaymentQueue.default().start(transaction.downloads)
}
case .failed:
SKPaymentQueue.default().finishTransaction(transaction)
didFailWithError(transaction.error)
case .deferred: break
case .purchasing: break
@unknown default:
fatalError("Unhandled case \(transaction.transactionState)")
}
}
}
func paymentQueue(_ queue: SKPaymentQueue, updatedDownloads downloads: [SKDownload]) {
downloads.forEach { download in
switch download.state {
case .waiting: break
case .active: break
case .paused: break
case .finished:
didPurchaseProduct(download)
case .failed: didFailWithError(nil)
case .cancelled: didFailWithError(nil)
}
}
}
Download Processing
do {
guard let url = download.contentURL else {
promise(.failure(.noContentURL))
return
}
print("download.contentURL =", url.absoluteString)
print("download.contentURL exists:", FileManager.default.fileExists(atPath: url.path))
let path = url.appendingPathComponent("Contents").appendingPathComponent("Content.json")
let data = try Data(contentsOf: path, options: .mappedIfSafe)
let package = try JSONDecoder().decode(CardPackage.self, from: data)
promise(.success(.didProcessDownload(package)))
SKPaymentQueue.default().finishTransaction(download.transaction)
} catch {
print(error.localizedDescription)
promise(.failure(.decodeErrorDidOccur))
SKPaymentQueue.default().finishTransaction(download.transaction)
}
The problem I am facing is the following. The SKDownload attached to the transaction has a contentURL which is not nil but which correspond to a folder that doesn't exist. These are the printed logs
download.contentURL = file:///private/var/mobile/Containers/Data/Application/EE97399D-974F-417A-AA50-969E3C238693/Library/Caches/StoreKit/13484324297981572924/
download.contentURL exists: false
The file “Content.json” couldn’t be opened because there is no such file.
Does anyone have any idea why this is happening and how to fix it?