Out of interest, can I ask what your code does in response to SKDownloadStateWaiting? We do nothing for SKDownloadStateWaiting in the paymentQueue:updatedDownloads: method - in the switch we simply break for that case.
As I'm sure you do, we call [[SKPaymentQueue defaultQueue] startDownloads:] elsewhere based on the transactions we receive in paymentQueue:updatedTransactions:.
Post
Replies
Boosts
Views
Activity
I've just been doing some more analysis. I don't see the crash you're experiencing, but as of beta 7 and 8 I see:
Some finished SKDownloads work as expected - a valid contentURL in the current app caches/StoreKit directory is provided and the content can be moved from there.
Some finished downloads arrive with a nil download.contentURL and there is sometimes an associated 'StoreKit' alert implying that the downloaded files couldn't be moved to the caches 'StoreKit' directory (~Library/Caches/StoreKit/) because there are existing files that should be moved or deleted. It is StoreKit that is managing the download of these files - we are intended to install the files from this location later on but how can we do it if StoreKit doesn't give us a valid download.contentURL? It seems as if StoreKit should be responsible for clearing the download path in the event that content exists there.
Some finished downloads arrive with the wrong content path - an app UUID in the folder path which does not correspond to the current home directory - and no content in that directory (not even when replacing the home directory UUID with the correct one).
A real example of the latter is a download that was started fresh in a current app session, and reported a contentURL.path of:
/private/var/mobile/Containers/Data/Application/D135A96C-9991-4BB6-BF98-87B52CD2B25D/Library/Caches/StoreKit/3968122711419134656/Contents when the current app home directory is different:
/var/mobile/Containers/Data/Application/E06F9149-D287-4D5A-BA08-6EA7DD469590/ No content can be found at the prior location, nor if we 'fix' the path by replacing the home directory UUID with the correct one for the current launch. You will see that kind of UUID mismatch for downloads started in previous app sessions, and actually updating the UUID will let you install the content if there is any, but in this case it just seems like the download finishes but there is no content whatsoever.
Beta 8 is still showing these same problems - we can receive SKDownloads in the SKDownloadStateFinished state with a 'nil' contentURL property (prior to finishing the associated transactions).
I must say it's getting a bit uncomfortable now!
We are also seeing -[NSURL initFileURLWithPath:]: nil string parameter exceptions when using content file paths from finished SKDownloads.
We don't see the crashes you're reporting, but it does seem like there are still download issues.
Now users are intermittently seeing:
"mzafbenc.15091114977934116907" couldn't be moved to "StoreKit" because an item with the same name already exists. To save the file, either provide a different name, or move aside or delete the existing file, and try again.
This is not due to any file management on our part - it seems to be StoreKit failing to deal with the possibility that it already downloaded certain content and that it wasn't moved.
I've just updated to iPadOS 14 beta 7 and can confirm that both of these issues seem to have been fixed:
paymentQueue:updatedDownloads: is called with SKDownloads in SKDownloadStateActive
'Sandboxing' errors have disappeared and Apple hosted content is downloaded to the app ~/Library/Caches/Storekit/ directory
I haven't confirmed on iOS yet - can anyone else say? Let's hope it's fixed across the board and stays that way into production. I'm leaving defensive code in my app which will fall back to copying files if moving them does not work. Lack of download progress would still be a problem but at least content would install if these issues reared their ugly heads again.
I'm glad to see this is not an issue isolated to our code. I filed feedback with Apple as of August 4th but have received no response as yet. I'll post here if and when I do.
As I can't edit my original post, here's a follow-up observation:
Under iOS 14, the SKDownload content appears to download to:
/private/var/mobile/Library/OnDemandResources/AssetPacks/StoreKit/… and not to the app's /Library/Caches/ directory which has been the case on iOS 13 and prior.
The former directory is not in the app sandbox, and it makes sense we don't have permission to mess with it. If I change my code to copy instead of move items, everything works as expected again.
Why the change? Apple documentation (at developer. apple. com/documentation/storekit/in-apppurchase/unlockingpurchased_content?language=objc) states:
In iOS, your app can manage the downloaded files. The StoreKit framework saves these files for you in the Caches directory with the backup flag unset. After the download completes, your app is responsible for moving these files to the appropriate location. For content that can be deleted if the device runs out of disk space (and downloaded again later by your app), keep the files in the Caches directory. Otherwise, move the files to the Documents folder and set the flag to exclude them from user backups. Therefore iOS 14 downloading to a different directory from which there is no permission to move files will break all apps that try to move files instead of copy them.
My guess is that the files are downloading there because of the SKDownload sandboxing error previously stated, and not because this is a wider change of behaviour under iOS 14. I couldn't see any mention of this anywhere in the release notes or documentation.
Can anyone official comment on whether this is an iOS 14 bug, a temporary scenario or whether this is set in stone from iOS 14 onwards?