Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Offline/cache support? #87

Closed
joemasilotti opened this issue Jul 13, 2022 · 10 comments
Closed

[Question] Offline/cache support? #87

joemasilotti opened this issue Jul 13, 2022 · 10 comments

Comments

@joemasilotti
Copy link
Member

This is a question, not a bug report or issue. Maybe we can enable GitHub Discussions for these types of conversations?

Are they any recommended approaches to caching data for offline access? I understand that the library won't do anything out of the box – I don't expect it to. But if folks have experience doing this I'd love some pointers.

For example:

  • What iOS APIs to use to download the payload?
  • Where to store/persist the cache?
  • How to invalidate it?
  • How to render it later when the internet connection is down?
  • Any other tips or gotchas.

I know HEY renders email content without a connections, so I know this is possible.

Any help, tips, or ideas would be greatly appreciated!

@jayohms
Copy link
Collaborator

jayohms commented Jul 18, 2022

I can provide a more comprehensive answer on HEY's approach later if you'd like (I'm just about to head out for the day), but here's the gist:

  • WKWebView does not provide sufficient APIs to intercept all document requests (for js/css/image resources) and provide an offline cached version. Android's WebView does provide an API, so it was significantly easier to provide offline support there via https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest)
  • You'll want all resources loaded on the same domain due to security implications
  • The only way we found to accomplish the above is to run a local proxy web server in the HEY iOS app to proxy all requests between the production server and WKWebView running the web app as localhost.
  • The proxy server caches resources as necessary and falls back to the cached version while offline.
  • This required all web app urls to be relative, which made supporting localhost much easier.

This was a pretty large effort of the team and a substantial amount of work. The current implementation was designed with some app-specific concerns, so it's not well abstracted as a portable implementation at the moment.

I'd love to hear if you come up with any other clever solutions, though. Because while the above approach works, it doesn't feel great as a long-term solution.

@joemasilotti
Copy link
Member Author

The more information the better, in my opinion! But this is a great peek under the hood; thanks for detailing how it works for HEY.

Do you notice any significant performance issues running everything through the local proxy server? And speaking of, did you roll your own or use one of the open source Swift packages?


I'm not currently trying to implement full offline access (yet!), but a small subset of pages. The goal is to make sure a user has access to specific screens even if they don't have service.

The approach I'm building looks like this:

  1. On app launch fetch a JSON array of the relevant objects to cache.
  2. Parse then serialize this JSON to disk, which includes HTML content.
  3. Render a native screen with these cached objects when no internet connection is detected.
  4. Render the cached HTML when tapping into one of these.

(I'm parsing then serializing to ensure there is no coding issues. Better to catch it when downloading then when trying to load it!)

This works pretty well, even if it requires a fair amount of additional, non-Turbo code. But I still need to style the cached HTML with downloaded stylesheets.

@izaguirrejoe
Copy link

This is just a shot in the dark, but I know that you can pass response HTML to a Session when visiting a URL. This is meant for form submissions, but could maybe be repurposed for caching? You could intercept requests and substitute cached HTML depending on online status. Since this is repurposing something meant for form submissions, I imagine there could be unintended side effects. This wouldn't work for assets unless there's a way to cache those as well.

@omohokcoj
Copy link

@jayohms did you use some custom built proxy server or GCDWebServer or some other proxy/server library?

@MichalSznajder
Copy link

I am experimenting with using Service Workers for caching. And so far I think it maybe be an elegant solution for this problem until we have Turbo Native support. I am developing my mobile app first on Android but I hope with Safari based web view it will be the same.

@owaiswiz
Copy link

@MichalSznajder AFAIK service workers don't work with WKWebView (which is what turbo native uses on iOS)

@connorproctor
Copy link

It appears service workers can work with WKWebView if you use App Bound Domains. I can't find official documentation, but there's Twitter discussion and I've seen some people on other forums saying it works.

Would service workers make it easier to support offline without having to reimplement every offline feature in native views?

@joemasilotti
Copy link
Member Author

Closing this out as there are no active plans to include this in turbo-ios.

@joemasilotti joemasilotti closed this as not planned Won't fix, can't repro, duplicate, stale Feb 22, 2024
@CARocha
Copy link

CARocha commented Feb 26, 2024

but @joemasilotti what was the best solution you came up with to work apps offline with turbo-native in ios and android?

@joemasilotti
Copy link
Member Author

I added offline access for a single feature for one of my clients. The company manages tours by matching tour guides to tourists.

On launch it downloads your next 30 days of tours to your device. And if you open the app without an internet connection it automatically switches to offline mode. Here you can view your upcoming tours, the meeting point, and contact information for your guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

8 participants