19 Replies
      Latest reply on Nov 8, 2019 9:19 AM by john daniel
      fergieee Level 1 Level 1 (0 points)

        Hi,

         

        I am loading a resource from a remote server and rendering its content in a WKWebView instance. I am configuring URLRequest object with a cachePolicy of .useProtocolCachePolicy and using the load(request:) method on the webview instance.

         

        The remote resource has a response header of Cache-Control: max-age=31536000. Yet the webview does not honour this cache policy. It always redownloads the remote resource.

         

        What other configurations are needed to ensure the resource is cached and persisted to disk for future cached loading? I see WKWebView uses a WKWebsiteDataStore object to persist cache. Is there something I need to configure there to get it to cahce correctly?

         

        Am I right in saying that WKWebView does not use the shared URLCache?

         

        Thanks!

        • Re: WKWebView - What configuration is needed to honour cache control headers?
          eskimo Apple Staff Apple Staff (12,305 points)

          Am I right in saying that WKWebView does not use the shared URLCache?

          No.  Web views do cache but, as with all web caching, there’s no guarantee that they will cache a specific resource.  I’m not sure why the web view hasn’t cached the resource you care about — I expect it’d make sense if you drilled down into the caching logic — but ultimately the decision as to what gets cache is the web view’s to make.

          If you require the web view to cache a specific resource, that’s no longer a cache but something more like an offline mode, and the web views do not support that in this way.

          Can you explain more about why you require this resource to be cached?

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: WKWebView - What configuration is needed to honour cache control headers?
              fergieee Level 1 Level 1 (0 points)

              Thanks Eskimo.

               

              I am developing an enterprise application where we are loading a web application into a WKWebView. For performance reasons, I would like the webview to cache resources that have cache control response headers. Resources such as index.html in a single page application for example.

               

              Due to some limitations out of my control, I need to bundle the entire web application into index.html so it is effectively one asset being downloaded which has a cache-control header with a large max-age in seconds. This is not for offline viewing, but for faster load times of the web application on subsequent loads.

               

              Since you replied to me I have been able to figure out why the the application wasn't being loaded from cache. There is a dynamic query string in the request leading to the browser thinking it is a different endpoint. I have noticed that it loads the web application from disk cache on first load of the web app into WKWebView. But if you try to reload the web applciation into the webview within the application, it does not load from either disk or memory cache, it loads from the network.

               

              Do you know why this would be the case?

               

              Regards,

              Fergal.

                • Re: WKWebView - What configuration is needed to honour cache control headers?
                  john daniel Level 4 Level 4 (500 points)

                  Most people have the opposite problem. WKWebView caches too much. Your dynamic query string is the most reliable trick to get WKWebView to force a re-download and avoid the cache. You seem stuck between a rock and a hard place here.

                   

                  However, you did mention "webview within the application". Since you do have everything inside one file, have you considered loading your webview directly from an HTML string? Are you sure you have the entire application in one file? Images too? If you did have additional files, you could use WKURLSchemeHandler to load them directly from memory too.

                    • Re: WKWebView - What configuration is needed to honour cache control headers?
                      fergieee Level 1 Level 1 (0 points)

                      Thanks John.

                       

                      I will be removing the query string to allow for client side caching so have removed myself from between the rock and a hard place

                       

                      The web application is remote and not local so not sure where loadHTMLStirng would come into play here. Your tip on WKURLSchemeHandler is a great one as this may help me overcome the limitations I have with the browser requesting assets such as JS and CSS for example.

                        • Re: WKWebView - What configuration is needed to honour cache control headers?
                          john daniel Level 4 Level 4 (500 points)

                          You can always pull the HTML directly (and other resources), not within the web view, and then display it as a string.

                           

                          Unfortunately, the new "WK" web views are still missing significant functionality compared to the old "legacy" web views. On iOS, Apple will no longer even accept apps built using the legacy web views. But on macOS Catalina, the "legacy" web views are required to print.

                           

                          Sadly, if you want to use Apple's APIs, in many cases, you simply have to beat it with a rubber hose to make it work. Be creative. Don't have mercy. You can write bug reports if you want, but don't sit on your hands and wait for them.

                            • Re: WKWebView - What configuration is needed to honour cache control headers?
                              eskimo Apple Staff Apple Staff (12,305 points)

                              On iOS, Apple will no longer even accept apps built using the legacy web views.

                              This is not true.  The app ingestion process currently issues a deprecation warning if you use UIWebView but it’s not actually blocked, and there’s been no announcement as to when that will change.

                              Share and Enjoy

                              Quinn “The Eskimo!”
                              Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                              let myEmail = "eskimo" + "1" + "@apple.com"

                                • Re: WKWebView - What configuration is needed to honour cache control headers?
                                  john daniel Level 4 Level 4 (500 points)
                                  eskimo wrote:

                                   

                                   

                                  This is not true.  The app ingestion process currently issues a deprecation warning if you use UIWebView but it’s not actually blocked, and there’s been no announcement as to when that will change.

                                  This is one of those times where truth is relative. This is not a trivial change. Someone doing advanced work with web views is going to have a major re-engineering effort ahead of them. In some cases, they will lose functionality. Anyone currently using UIWebView, or its equivalent on macOS, needs to start this re-engineering effort immediately. That way, they can research workarounds, such as embedded web servers, or even file bug reports. It would be a very bad idea to wait until apps start crashing, apps can't be submitted at all, or even an offical announcement. While there is no way to avoid letting Apple dictate a development schedule, one can, at least, try to prevent it from becoming a crisis.

                            • Re: WKWebView - What configuration is needed to honour cache control headers?
                              fergieee Level 1 Level 1 (0 points)

                              Does WKURLSchemeHandler support intercepting http/https requests? Doesn't look like it from reading up on this. Think its custom protocols only?

                                • Re: WKWebView - What configuration is needed to honour cache control headers?
                                  john daniel Level 4 Level 4 (500 points)
                                  fergieee wrote:

                                   

                                   

                                  Does WKURLSchemeHandler support intercepting http/https requests? Doesn't look like it from reading up on this. Think its custom protocols only?

                                  No. It is only for custom protocols. One of the common complaints about WKURLSchemeHandler is that it doesn’t support intercepting http and https.

                                   

                                  In my case, I have a custom protocol “estp:” that reads data directly from a local cache. You can specify a baseURL for resources and that baseURL can use your custom protocol. Then you never need to explicity refer to the custom protocol in your HTML.

                                   

                                  I used to include an embedded web server in the app. It sure felt good to remove all of that code, but I can't honestly say it was worth it. Maybe it will be better for iOS.

                                    • Re: WKWebView - What configuration is needed to honour cache control headers?
                                      fergieee Level 1 Level 1 (0 points)

                                      I ended up implementing a WKURLSchemeHandler for browser requests such as js and css files as they need to be intercepted for authorization purposes. However, it looks like the browser waits syncronously for all the urlSchemeTasks to be completed before the browser renders the page. Do you know if a way to asyncronously load these resources?

                                       

                                      For example. I download a html page and the html page has custom protocol references for js and css files. These are downloaded in the scheme handler using a URLSession client. But it looks like the browser waits for these files to be downloaded before the html page is rendered. Is that expected?

                                        • Re: WKWebView - What configuration is needed to honour cache control headers?
                                          john daniel Level 4 Level 4 (500 points)

                                          That sounds reasonable. The browser can't really the rest of the page without those resources. You can sometimes see this in Safari if you have a flaky server or poor connection. If you cancel the load, you can get a corrupted HTML page with no styling.

                                           

                                          What I think you need here is a separation of responsibilities. WebKit is not flexible. It does what it does and the more unusual your code, the greater the risk. My suggestion would be to have a REST service for this data. Your app can request the resources and use a native interface for any authentication. The, once it has everything, it can render it in a web view.

                                           

                                          Another option might be to serve intermediary placeholders. Once you get the real data, you can then issue a refresh with the real data.

                                  • Re: WKWebView - What configuration is needed to honour cache control headers?
                                    eskimo Apple Staff Apple Staff (12,305 points)

                                    But if you try to reload the web applciation into the webview within the application

                                    Reload by calling load(request:)?  Or reload by calling reload?

                                    Share and Enjoy

                                    Quinn “The Eskimo!”
                                    Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                                    let myEmail = "eskimo" + "1" + "@apple.com"