asynchrony / Re-Lax

Recreating Parallax on tvOS
MIT License
156 stars 16 forks source link

TopShelf example not working since tvOS 13.4 #4

Open tmm1 opened 4 years ago

tmm1 commented 4 years ago

In tvOS 13.4+ and 14.0 Beta, there are much stricter memory limits on top shelf extensions. The example seems to use a lot of memory and gets killed, but that can be fixed as so:

--- a/ReLaxExample/ReLaxTopShelfExample/ServiceProvider.swift
+++ b/ReLaxExample/ReLaxTopShelfExample/ServiceProvider.swift
@@ -8,7 +8,7 @@ class ServiceProvider: NSObject, TVTopShelfProvider {
     private let posterImages: [ParallaxImage] = titles
         .map { $0.lowercased().components(separatedBy: .whitespaces).joined() }
         .map { movie in
-            ["5", "4", "3", "2", "1"].map { return "\(movie)-\($0)" }
+            ["5"].map { return "\(movie)-\($0)" }
         }
         .compactMap {
             $0.compactMap { UIImage(named: $0) }

However, it seems that now disk based urls cannot be used for images in the top shelf. The image is never rendered on screen:

Screen Shot 2020-07-23 at 5 13 04 PM

tmm1 commented 4 years ago

https://github.com/asynchrony/Re-Lax/blob/38739c2e30ae554ec78704576e4509190324794c/ReLaxExample/ReLaxTopShelfExample/ServiceProvider.swift#L25

This returns a URL like file:///var/mobile/Containers/Data/PluginKitPlugin/523B8F53-D249-461C-B789-15E186677923/Library/Caches/ which used to work for serving images to the top shelf, but seems no longer does.

marksands commented 4 years ago

Oof--thanks, @tmm1. I'll see if there's any workarounds, but I'll likely have to ~shout into the void~ file a radar about this. I spoke with one of the tvOS engineers a few years back and he assured me loading URLs from the cache to be displayed in top shelf is expected behavior, but sounds like that might've changed. 😞

tmm1 commented 4 years ago

Yea, real bummer.

I just opened a radar too, for reference:

FB8122159 TVTopShelfSectionedItem with file:// based imageURL does not display

Before tvOS 13.4, a top shelf extension could generate/save images in the cache directory and then serve them into the top shelf using setImageURL: with the file:// based URL for the image on disk.

After 13.4 and in tvOS 14 Beta 1/2/3, the images are no longer displayed. See attached image.

marksands commented 4 years ago

If any Apple 👀 are watching, I filed two radars: FB8122798 and FB8122874.

laurent-humbert commented 4 years ago

You only have a nano second to provide the TVTopShelfSectionedContent. It's not possible to issue even the simplest http request, or generate a thumbnail using UIGraphicsImageRenderer etc. All that work has to be done by the app, (in a BGAppRefreshTask probably) and the resulting data (thumbnails etc...) saved in a group folder. Then it's fine to just use the file url.

tmm1 commented 4 years ago

You only have a nano second to provide the TVTopShelfSectionedContent. It's not possible to issue even the simplest http request, or generate a thumbnail using UIGraphicsImageRenderer etc.

Not sure I follow. I'm making HTTP requests and it works just fine. The new TVService api in 13.0 uses a completion handler to make this even easier. Apple's own BuildingAFullScreenTopShelfExtension example uses dispatch queue to calculate the top shelf contents, and even mentions a network request in the code comments.

I also tried already to cache the generated files and even when they're ready on disk and returned right away, it never renders inside the Top Shelf.

saved in a group folder

Maybe this is the key.. what do you mean by group folder?

tmm1 commented 4 years ago

Maybe this is the key.. what do you mean by group folder?

Okay I can confirm this works. See https://developer.apple.com/forums/thread/23418

file:///var/mobile/Containers/Data/PluginKitPlugin/523B8F53-D249-461C-B789-15E186677923/Library/Caches/

The new path with proper permissions to render inside Top Shelf looks like file:///private/var/mobile/Containers/Shared/AppGroup/2F333855-1798-4D86-9C92-E8E9D45C0119/Library/Caches/

marksands commented 4 years ago

Awesome--I'll be unavailable for most of the weekend but I'll experiment and correct the example code as soon as I can.

laurent-humbert commented 4 years ago

You only have a nano second to provide the TVTopShelfSectionedContent. It's not possible to issue even the simplest http request, or generate a thumbnail using UIGraphicsImageRenderer etc.

Not sure I follow. I'm making HTTP requests and it works just fine. The new TVService api in 13.0 uses a completion handler to make this even easier. Apple's own BuildingAFullScreenTopShelfExtension example uses dispatch queue to calculate the top shelf contents, and even mentions a network request in the code comments.

Like you at first I was happy to see the completion handler. But I couldn't get any http request to complete (It does work in the Simulator though). Maybe they have fixed it in more recent version of iOS 13.

I also tried already to cache the generated files and even when they're ready on disk and returned right away, it never renders inside the Top Shelf.

saved in a group folder

Maybe this is the key.. what do you mean by group folder?

The new path with proper permissions to render inside Top Shelf looks like

It's bizarre the extension wouldn't have read access to its own Cache folder.