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

[BUG] iOS WKWebView caches old PDF blobs #4835

Open
ncpunt opened this issue Oct 17, 2024 · 10 comments
Open

[BUG] iOS WKWebView caches old PDF blobs #4835

ncpunt opened this issue Oct 17, 2024 · 10 comments

Comments

@ncpunt
Copy link

ncpunt commented Oct 17, 2024

What happened?

If I use the following code to view a dynamically generated PDF on iOS-WKWebView using jsPDF, the same (first) PDF is shown regardless of any changes to later generated PDFs.

let a = document.createElement("a") 
a.download = "report.pdf";
a.href = doc.output('bloburl');
a.click();
document.body.removeChild(a)

The only way to show fresh PDF contents is to randomize the filename.

a.download = crypto.randomUUID();

Does anyone know an alternative method because I am a bit worried the cached files will pile up. I am also reluctant changing the Swift code generated by PWABuilder.

How do we reproduce the behavior?

Use the code in the description.

What do you expect to happen?

Behavior as in all other browsers where this is not required.

What environment were you using?

Physical iPhone 12 device (iOS 18) and a iOS Simulator on an Intel Mac

Additional context

All browsers and all platforms do not have this problem with the exception of iOS WKWebView.

@jgw96
Copy link
Contributor

jgw96 commented Oct 23, 2024

@maiconcarraro any ideas here? Or maybe @khmyznikov

@maiconcarraro
Copy link
Contributor

@jgw96 I can explore later this week,

@ncpunt can you share a demo github project using this? so I can clone and host it to generate the ios package and debug it. having only the snippet will take a longer time to have everything set up correctly and can lead to side effects.

@ncpunt
Copy link
Author

ncpunt commented Oct 24, 2024

Repo: WKWebViewCache
Link: Host

@ncpunt
Copy link
Author

ncpunt commented Oct 24, 2024

If you run this on Windows in Chrome, you will see that Chrome automatically generates a randome file name.
image

@maiconcarraro
Copy link
Contributor

@jgw96 @ncpunt I found the root cause, inside of download function it returns the file by suggested name:

image

so using the same name, will return the existing file, even if you have different blobs:

Optional("blob:https://www.medimatics.nl/f8c71cb4-59dc-4313-9860-a65e66d44f42")
file:///Users/user/Library/Developer/CoreSimulator/Devices/98206E0A-8A95-409E-AC8A-08994C38A89F/data/Containers/Data/Application/DCE0F696-CA1D-43C4-A2BE-BAFC43C5B50F/Documents/mypdf.pdf

Optional("blob:https://www.medimatics.nl/4b91cc45-ae31-4bfd-ad0b-265d669ec748")
file:///Users/user/Library/Developer/CoreSimulator/Devices/98206E0A-8A95-409E-AC8A-08994C38A89F/data/Containers/Data/Application/DCE0F696-CA1D-43C4-A2BE-BAFC43C5B50F/Documents/mypdf.pdf

You can fix this by making sure to remove the previous file:

func download(_ download: WKDownload, decideDestinationUsing response: URLResponse,
                suggestedFilename: String,
                completionHandler: @escaping (URL?) -> Void) {

        let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let fileURL = documentsPath.appendingPathComponent(suggestedFilename)
        
        // Remove existing file if it exists
        if FileManager.default.fileExists(atPath: fileURL.path) {
            try? FileManager.default.removeItem(at: fileURL)
        }

        self.openFile(url: fileURL)
        completionHandler(fileURL)
    }

see FileManager.default.removeItem above. using this approach solved the situation on my debugging session.

@maiconcarraro
Copy link
Contributor

maiconcarraro commented Oct 27, 2024

@ncpunt

If you run this on Windows in Chrome, you will see that Chrome automatically generates a randome file name.

that's not right, you have a different condition for non-ios device, both have a random blob file name, if you simulate an ios userAgent for the chrome and click it will download the file, and if you click again it will show again to download same file... but windows/chrome will make sure to keep both files and renaming the second:
image

which was the problem for the ios, it wasn't renaming or making sure to delete old file, if you want to always guarantee an unique file, I do recommend to add timestamp to your file name, in case you can't... you can modify your xcode project to include the fix above.

@ncpunt
Copy link
Author

ncpunt commented Oct 28, 2024

I did not realilze that "doc.output('bloburl')" would already generate a random filename.
I am happy with my workaround without touching the Swift code. Will you make changes to the code generated by PWABuilder?

@jgw96
Copy link
Contributor

jgw96 commented Nov 12, 2024

@ncpunt or @maiconcarraro would one of yall want to make a PR for this change? Our iOS platform is mainly community driven

@maiconcarraro
Copy link
Contributor

@jgw96 I sent on same day: pwa-builder/pwabuilder-ios#69

Copy link
Contributor

This issue has been marked as "needs attention 👋" since it has not been triaged for 7 days. Please triage the issue .

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

No branches or pull requests

3 participants