I'm able to build and run the TV app with the TVTopShelf extension on simulators and physical Apple TVs but I get an error when I try to validate (or distribute) the archive built from XCode. The error says:
App Store Connect Operation Error - Asset validation failed
The log files don't provide more information:
"Error Domain=ContentDelivery Code=90362 "App Store Connect Operation Error" UserInfo={IDEDistributionIssueSeverity=3, NSLocalizedDescription=App Store Connect Operation Error, NSLocalizedRecoverySuggestion=Asset validation failed}"
As far as I know the certificate, the identifiers and the provisioning profiles for both the tvOS app and the TVTopShelf extension are OK. When I choose to manually select signing options, I can set the provisioning profiles for both the app and the extension and XCode does not complain about them.
Is there something specific to know when distributing an app with an extension app? Is there some configuration to set on AppStoreConnect side? Or common pitfalls to avoid?
Thanks for your help.
Post not yet marked as solved
My app only offers consumable in-app purchase products.
I can successfully purchase a product once but when I try to purchase it again, a popup "This In-App purchase has already been bought. It will be restored for free." appears and the first transaction is restored: the payment queue delegate is notified that a new transaction (with the same identifier as the successful transaction) is updated to the purchased state. I never get a purchased transaction with a new identifier and hence I consider that the purchase failed.
Also, each time the app is put in foreground again or at startup, the payment queue delegate is notified that a transaction has been updated (as if it had never been finished). Even though the app properly finishes the transaction each time.
Side notes: I guarantee that all purchased or failed transactions are finished (confirmed by the removedTransactions SKPaymentQueueDelegate method being called each time). I even tried to call finishTransaction from the main thread with no success.
Right before the subsequent purchase attempts, the transactions queue is empty.
I'm also pretty sure I was able to purchase several times the same product last week, with no change in code (same app version from Testflight).
I observe this behaviour when building the app with Xcode or when distributed via Testflight. It has not been published yet so I cannot check how it behaves in the Production environment.
Do you have any clue on what's going on? Could it be a side effect of using the Sandbox environment?
Thanks for your help,
Aurélien.
What follows is about tvOS 15 but may also apply to iOS 15.
Our app may display several types of UICollectionView cells and it depends on the content sent by our backend. Prior to tvOS 15, we used to lazily instantiate UICollectionView cell registrations when needed for the first time while building a UICollectionViewDiffableDataSource. Eventually, each cell registration is only instantiated once (or never).
Now tvOS 15 throws an exception when doing so, pretending to prevent the app from creating a new cell registration each time. And it does not care whether it's actually a new cell registration each time or one that is lazily instantiated once.
Here is the exception:
*** Assertion failure in -[UICollectionView dequeueConfiguredReusableCellWithRegistration:forIndexPath:item:], UICollectionView.m:7413
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempted to dequeue a cell using a registration that was created inside -collectionView:cellForItemAtIndexPath: or inside a UICollectionViewDiffableDataSource cell provider. Creating a new registration each time a cell is requested will prevent reuse and cause created cells to remain inaccessible in memory for the lifetime of the collection view. Registrations should be created up front and reused. Registration: <UICollectionViewCellRegistration: 0x6000000f8c60>'
I understand the concern but lazy instantiation is a thing and it should not be for forbidden for the sake of best practices that are not related to it. In my humble opinion, this assert should be removed and apps should be allowed to create cell registrations on the fly.
Post not yet marked as solved
When using rounding methods (rounded(), rounded(toPlaces:), round(_: CGFloat)) on CGFloats with the simulator, the returned value is not rounded at all or sometimes makes no sense at all.
(lldb) po (398.0 / 165.0).rounded()e-321
The expression may even crash when called from an attached debugger (the following expression returns 2.4121212... when no debugger attached):
(lldb) po (availableWidth / (cellRatio * (tileType.sectionHeight - 50))).rounded()
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x7c).
The process has been returned to the state before expression evaluation.
The same operations are OK on a real device or in a playground on a Mac. It's also OK when converting the CGFloat to a Float and calling roundf() as follows:
(lldb) po CGFloat(roundf(Float(availableWidth / (cellRatio * (tileType.sectionHeight - 50)))))0
Finally here are the results when passing various rounding rules to the rounded() method: .toNearestOrAwayFromZero: crash in debugger
.toNearestOrEven: 2.412121212121212 (unchanged value)
.up: inf
.down: 2.412121212121212 (unchanged value)
.towardZero: 2.412121212121212 (unchanged value)
.awayFromZero: inf
Is there something wrong with computing rounded values of CGFloats on a simulator?
Post not yet marked as solved
We want to allow the enduser to purchase movies from our VOD app using in-app purchases (IAP). Since our app exposes thousands of movies, we plan to create several generic consumable IAP products, one by price tier (according to the expected selling prices). Each productId can be used to buy different movies.
Once a purchase is successful (transaction in purchased state), our app needs to send the transaction id and receipt along with the movie id to our back-office in order to perform checks and eventually mark this specific movie as purchased for this user (our app being multi-platform, the purchased movies have to be available on all platforms, whatever the platform used for the purchase).
But since the purchase is solely based on the SKProduct (hence its id), and since there's no way to attach some kind of userInfo to the SKPayment added to the default SKPayementQueue, there's no direct way to match an SKPaymentTransaction to the movie whose purchase triggered its creation, especially when dealing with "Ask to Buy" and highly asynchronous transactions updates.
So, as far as I know, I have to maintain some sort of permanent context with the movie id, the product id and the last update date in order to try to get the movie id matching a transaction. But there are lots of things to take care of and a high risk maintaining this parallel context synced with the SKPaymentQueue pending transactions.
I am pretty sure other apps have the same IAP strategy so I wonder if I'm missing something obvious. Are there some recommendations from Apple on the way to handle it? Or has anyone been through this road and being able to provide advices?
Thanks for your help,
Aurélien.
Post marked as Apple Recommended
Our iOS apps use to embed and sign third party frameworks built for various architectures (i386 x86\_64 armv7 arm64). When building an archive, a script phase strips unwanted architectures (simulator ones) from the build.
Everything was working fine until XCode 12.3 (updated this morning). Now, what seems to be a "Target integrity" check always reports the following error for these embedded frameworks (example with GoogleCast framework):
error: Building for iOS, but the linked and embedded framework 'GoogleCast.framework' was built for iOS + iOS Simulator. Also, as these frameworks are synced from a server at build time using a script phase, if I delete the frameworks before compiling, there are no errors and the app is built properly. But if the frameworks are already synced, the compilation systematically fails right away.
Finally, other frameworks with the same architectures but that are not embedded don't trigger this error.
I've tried to changes some build settings regarding the architectures but with no success.
Could you please tell me how to embed these frameworks, keeping in mind they are third-party frameworks?
Cheers,
Aurélien
Post not yet marked as solved
For Q&amp;A and logging purposes, I need to know whether the response to an URLSessionDataTask comes from the URLCache or not.
I've read here and there that it was just a matter of comparing the cachedResponse before and after receiving the dataTask response. But it does not work as each call to URLCache.shared.cachedResponse(for: urlRequest) returns a new instance of CachedURLResponse (each one having another new instance of HTTPURLResponse).
Am I missing something? Is there another way to tell if the response comes from the cache?
Post not yet marked as solved
Hi,
We develop an app that sends multicast requests on the local network in order to look for our proprietary hardware (using sockets) and I understand that it now requires the Multicast Networking entitlement (for which I've applied and received no response from Apple yet).
However, I'm concerned about the app currently in production on the App Store, and how it behaves on various versions of iOS. Especially, it seems our app (built with Xcode 11) is still able to send multicast requests even if run on an iOS 14 device. However the app built with Xcode 12 systematically fails to send requests on the local network (through CFSocketSendData) on the same iOS 14 device, the local network access being properly granted by the user.
Hence my questions: Is the Multicast Networking entitlement only required for apps built since iOS 14 is available (so with Xcode 12)? If so, how long do we have before an update is required with the proper entitlement? Or have I missed something?!
Thanks for your time.
Post not yet marked as solved
I'm displaying a translucent UIToolbar as a subview of a UIViewController which is a child of a UINavigationController (I don't use the UINavigationController toolbar as I want to subclass it).
Everything works fine but one thing: when I push another UIViewController on the UINavigationController stack, the next UIViewController edges are not extended behind the NavigationBar until the animation is over. The same issue occurs when the pop animation of the next UIViewController starts.
Side notes: The NavigationBar is translucent (by default)
Both UIViewControllers are set to extend edges under top and bottom bars
The issue is not reproducible if the UIToolbar is not translucent (of if a tint is set).
The same issue occurs if the UINavigationController is inside a UITabBarController: the next UIViewController edges are not extended under the tabBar.
It's easily reproducible on iOS 12, iOS 13 and iOS 14 devices/simulators, with no code, just storyboard editing.
Here's a link to the StackOverflow post I've created a month ago with no feedback from the community:
https://stackoverflow.com/questions/63424459/uiviewcontroller-edges-not-extended-behind-top-bottom-bars-during-a-uinavigation