11

I have a large (>1GB) in-app purchase that I want to deliver using an Apple-hosted download. The Apple docs say the Apple-hosted IAP content doesn't have a limit to the size that can be downloaded on a cellular connection. I'd like to be able to ensure the purchase is only allowed when connected by WiFi.

There's the possibility that during download the user might walk out the door and transition to cellular. At that point I'd like to pause or cancel the download until WiFi was available again.

I raised a TSI and Apple's response was "Our engineers have reviewed your request and have concluded that there is no supported way to achieve the desired functionality"

It seems feasible to use Reachability to check the connection type before starting the download and use the observer delegate during the download to make sure the phone didn't switch to cellular.

Will this work reliably? Is there a better way to do this?

Also in terms on maintaining control as the download proceeds, it's not clear from the Apple docs if the Apple-hosted download that runs in the background is in my app's process, or it happens out of process. In other words, if my app is terminated, is the download guaranteed to be stopped or does it continue outside my app's control?

Update: With the benefit of some experience, the question is somewhat moot. Continuous download of data requires that the phone has a WiFi connection and external power. Without these, the download gets paused a little while after the screen powers off - phone's power management I guess. Also the IAP download is out of process, it continues even of your app crashes (explicitly killing the app stops the download though). When your app restarts the StoreKit delegates are called to complete the download and purchase.

John Mac
  • 2,530
  • 4
  • 24
  • 30
  • 3
    Please don't. Show the user a warning that the download is enormous and let them decide. But don't simply disallow downloading it over cellular. – Undo Dec 13 '13 at 20:47
  • 1
    Well that's one way of looking at it. The way I look at it is the consequences of a user not reading the warning or, more likely, forgetting a download is in progress and leaving wifi can be so severe, I don't want to go there if I can avoid it. Cell overage charges are $100-$500/GB in many places and international roaming charges can be over $10,000/GB. Google will give you a sense of the intense emotions this generates – John Mac Dec 13 '13 at 23:38
  • Apple disallows large (over 50MB) app downloads over cellular. I don't see applying the same logic to very large in-app purchase content as anything different. – BergQuester Dec 16 '13 at 22:06
  • 1
    Before anything else, you should open a feature request over at https://bugreport.apple.com – Léo Natan Dec 16 '13 at 22:10
  • BergQuester - exactly. Leo Natan - already done this, the best solution is if SKDownload handles this. – John Mac Dec 17 '13 at 03:07
  • @JohnMcC Please see my answer for a possible solution using `SKDownload`. – Léo Natan Dec 17 '13 at 09:09
  • @JohnMcC - Here's the problem though: You don't know what their cellular plan is. They might have an unlimited plan. They might have no plan at all. You're assuming that their plan isn't adequate but that whatever WiFi plan they have is. Your assumptions could be very wrong. Some cellular carriers have unlimited plans. Most WiFi plans have monthly limits that 99.9% of users never come even remotely close to hitting. Just warn the user. If they ignore it, that's their problem, or the cellular provider's problem, or Apple's problem. It's anyone's problem but yours - don't make it yours. – ArtOfWarfare Dec 18 '13 at 15:57
  • @ArtOfWarfare really what I want to do is the same as what happens for apps. Globally, most people don't have unlimited cellular plans and the cost of forgetting and walking out the door in the middle of a download could be a several hundred dollar cellphone bill. Strictly speaking not my problem, but you know where the anger will be directed... – John Mac Dec 18 '13 at 20:24
  • @JohnMcC - So warn the user when they switch from being on WiFi to being on cellular. Trust your user isn't an idiot and that, properly warned, they can make the right choice. Assuming your user can't make this choice on their own is just going to result in angry users who want to spend money now, but you won't let them. – ArtOfWarfare Dec 18 '13 at 23:46
  • @JohnMcC Have you attempted an implementation of my proposed answer? – Léo Natan Dec 23 '13 at 04:22
  • 1
    @LeoNatan I've had a quick look at it and I think you're right that there's no way to keep control of it, especially of your app is terminated or backgrounded. Going to go with NSURLSession, as you suggest. – John Mac Dec 23 '13 at 21:19
  • Take Note: Apple has recently changed the maximum download file size from 50MB to 100MB since iOS 7. Still might be wise to notify the user of the size of the download >50MB. – Danoli3 Jan 23 '14 at 00:01

1 Answers1

5

You can write a "download manager" which would monitor network status, and call pauseDownloads: and resumeDownloads: on the payment queue. Take a look here how to observe network changes.

Regarding download in-process vs. a dedicated process, I think it happens in-process. Taking a look at the API, we are told to queue SKDownload objects only when the transaction state is SKPaymentTransactionStatePurchased, but there is no API where we can obtain all purchased-state transactions and currently have queued downloads (like we have in the new NSURLSession API, where one of the modes handles downloads in an external daemon). This, and some experience with apps that have crashed exactly when trying to download leads me to believe it is in-process. In these apps that crashed, I had to restore purchases for download to start again, which is compatible with the exposed API in StoreKit.


Another suggestion is, if you could host the content by yourself, you could use Apple's new NSURLSession API, where you can specifically tell it to only download over WiFi.

Community
  • 1
  • 1
Léo Natan
  • 56,823
  • 9
  • 150
  • 195
  • Leo, took your advice in the end and used the background transfer service. I found large Apple-hosted downloads would sometimes just stop part way through, but NSURLsession appears rock solid. Also had a problem where [[SKPaymentQueue defaultQueue] restoreCompletedTransactions] sometimes replays only some or none of the transactions, which is a serious issue if the downloads are Apple-hosted. – John Mac Mar 26 '14 at 03:31