Questions about Webview
I am building a webview to present a specific website. There are some questions:
Is it possible to have persistent web cache between sessions? The webview is for just one site so keeping cache could save traffic and time downloading resources.
I make webview a subview of a UI View and present the UI view in landscape fullscreen. Since I hide title bar, I can only double-finger swipe down to close. However after I close the view, the webview seems to be still running in the background. Any way to completely close it except for closing Pythonista?
Any help will be welcomed.
Looks like you can instantiate a NSURLCache , with a disk path pointed it a folder, and set sharedCache=your new cache.
That would let you reuse the cache across app starts, though files may get deleted when they expire, or iOS decides disk space is low.
I have made some searches and constructed a piece of code.
NSURLCache = ObjCClass('NSURLCache') shared_cache = NSURLCache.alloc().initWithMemoryCapacity_diskCapacity_diskPath_(100*1024*1024,500*1024*1024,"kc") NSURLCache.setSharedURLCache_(shared_cache)
Tested. Look like it does not preserve and reuse caches. Is there any mistake?
You might try os.path.abspath('kc'). And of be course make sure kc actually exists.
It is possible you have to point to the caches folder.
No luck. I tried
No file was written to the directory.
@Neso, from the docs:
”In iOS, path is the name of a subdirectory of the application’s default cache directory in which to store the on-disk cache (the subdirectory is created if it does not exist).”
To me this looks like your first attempt should have been successful. Maybe if you try a full path to the cache directory? (Need to find out what that directory is, first.)
yep, I tried both ways. The strange thing is, I cannot find the cache directory in either cases. Answers from stackoverflow tell that the cache directory is located in “Library/Cache” but no directory or file was there. I did some searches using stash however cannot find anything related. So it is possible that cache is not created from the very beginning.
My code structure is like:
NSURLCache = ObjCClass('NSURLCache') shared_cache = NSURLCache.alloc().initWithMemoryCapacity_diskCapacity_diskPath_(100*1024*1024,1200*1024*1024,'kc') NSURLCache.setSharedURLCache_(shared_cache) w, h = ui.get_screen_size() v = ui.View(background_color='black') wv =ui.WebView() ......
shows the caches folder. there, under com.omz-software.Pythonista3 you will find your kc folder.
how you force your webview to use the cache is another story maybe. what website are you trying to use?
NSURLRequest = ObjCClass('NSURLRequest') v=ui.WebView() v.present() r=NSURLRequest.requestWithURL_cachePolicy_timeoutInterval_(nsurl('https://example.com.'),2,10) v.objc_instance.webView().loadRequest_(r)
seems to do the trick. cache policy 2 is to try the cache first, then only load if the cache misses. i was able to turn off networking and run the script again, after quitting pythonista
Thank you very much. Now I can finally locate the cache folder. There are three files: cache.db, cache.db-wal and cache.db-shm. So the cache is initialized successfully. I ran the code you provided. The size of these files are not changed. I guess the cache has not been used?
The website is a browser gaming site. It will download resources (mainly image) during start-up. I am trying to figure out a way to avoid repeated downloading.
did you look at share_cache.currentDiskUsage() and share_cache.currentMemoryUsage()?
one problem is that depending on how the site handles resources, they might appear as different resources every time to the cache. i.e if there is some unique identifier included in the get requests. i think the ios cache caches things based on the request url, not resulting file -- i.e two requests that look different but return the same file might not result in a cache hit.
there are ways to "pre fill" the cache, if you know what those requests look like in advance. or basically you have to override some of the urlrequest methods to be smart enough to strip off the auth info, etc when lookin in the cache. i think, at least
I would like to force writing cache to the disk so I set memorycapacity as 0 (don’t know whether this is right). The disk usage of cache is about 110k. Almost no change after several times of reloading the site.
Do cached requests have to be in the same domain with “NSURL”? There is a redirect during site loading. Wondering whether this is relevant.
Requests have the same domain. The format is like:
The modification date of the cache files changes so cache is actually affected. However don't know why large images do not get cached.
Yeah, not sure if webview only caches the specific request, or all the subsequent requests. The cache policy is what is important, and not sure if we can control that otherwise.
I suspect there are some delegate methods in uiwebview that involve requests that you can intercept and set the cache policy... If you can find examples on stack overflow (Uiwebview cache policy), we can implement it in Python. I didn't do a thorough search
I think the key is to find a way making nsrequest cache images. I ran share_cache.currentMemoryUsage() during the site loading. The memory usage is very small.