Как мне справиться с неудачной загрузкой SKDownload?
При обращении SKDownload
обновления я не уверен, как реагировать на .failed
государство.
Я видел руководство, опубликованное на форуме разработчиков Apple, но это означает, что я должен дождаться выхода пользователя и перезапустить приложение, чтобы возобновить загрузку.
Позже, когда пользователь перезапускает приложение и метод addTransactionObserver вызывается во время запуска, наблюдатель транзакции обнаружит incompleteTransaction и уведомит приложение с помощью метода делегата updatedTransactions. Приложение может повторить попытку загрузки размещенного контента.
Вопреки этому, в этом уроке я получил указание сделать обратное и завершить транзакцию, чтобы позволить пользователю повторить попытку загрузки, восстановив покупку.
Существует несколько способов улучшить взаимодействие с пользователем, даже если загрузка не удалась...... Мы могли бы завершить транзакцию, и пользователь может использовать кнопку восстановления для загрузки файлов.
Если мы даем пользовательские опции, то транзакция не должна быть завершена до тех пор, пока мы не убедимся, что мы больше ее не используем (например, если вы планируете возобновить загрузку позже, не завершайте транзакцию).
Это означает, что я могу возобновить неудачную загрузку. Это возможно?
мой paymentQueue: updatedDownloads
Метод ниже:
public func paymentQueue(_ queue: SKPaymentQueue, updatedDownloads downloads: [SKDownload]) {
downloads.forEach ({ (download) -> Void in
switch download.state {
case .active:
// Update the UI to allow user to pause/cancel download
case .cancelled:
// Update UI to show download cancelled
queue.finishTransaction(download.transaction)
case .failed:
let description = download.error?.localizedDescription
// <-------------------- retry the download? What should I do here?
case .finished:
// Update the UI to reflect download complete
queue.finishTransaction(download.transaction)
case .paused:
// Update the UI to allow user to resume download
case .waiting:
// Begin download immediately, on advice of: https://stackru.com/a/23602553/3718806
queue.start([download])
}
})
}
Я ожидаю, что мои пользователи смогут повторить неудачную загрузку без перезапуска приложения.
Как мне этого добиться?
2 ответа
На случай, если это кому-нибудь поможет, я решил:
- Завершите транзакцию, так как Apple рекомендует это, и у нас, похоже, нет выбора *
- Отображать сообщение об ошибке для пользователя, так как всегда будет одно
- Замените кнопку "Купить" на кнопку "Повторная загрузка". (т. е. сделать вид, что пользователь успешно загрузил контент и впоследствии удалил его)
- Когда кнопка "повторная загрузка" нажата, попытайтесь приобрести ее снова, и пусть storekit автоматически откажется дважды взимать плату с пользователя и предложит ему снова загрузить контент.
Код ниже:
public func paymentQueue(_ queue: SKPaymentQueue, updatedDownloads downloads: [SKDownload]) {
downloads.forEach ({ (download) -> Void in
switch download.state {
...
case .failed:
queue.finishTransaction(download.transaction)
let description = download.error!.localizedDescription
// show error to user
// change 'buy' button text to read 'redownload'
...
}
})
}
// later, when 'redownload' is tapped to buy the same SKProduct
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
Заметки:
* поскольку нет способа возобновить неудачную загрузку (насколько я могу судить, кто-нибудь, пожалуйста, исправьте меня, если я ошибаюсь).
SKPaymentQueue.default().add(SKPayment(product: skProduct))
Это безопасно, потому что StoreKit представит использование с предупреждением "Вы уже приобрели это. Хотите получить его снова бесплатно?", и это именно то, что я хочу. Когда пользователь примет это, он начнет загрузку снова.
Это неуклюжий способ перезапустить загрузку, но, похоже, это самый Apple-кошерный способ сделать это из всех, что я могу найти.
for download in downloads {
switch download.downloadState {
case .active:
// deal with active
break
case .failed:
// inform the user the download failed
// should I close the transaction here? ie:
SKPaymentQueue.default().finishTransaction(download.transaction)
break
// cut code...
}
} // end each download