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

[iOS] - Add ability to download and install PKPasses (Bundled) #27258

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Brandon-T
Copy link
Contributor

Summary

  • Add support for PKPass bundles

Resolves brave/brave-browser#43338

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally:
    • npm run test -- brave_browser_tests, npm run test -- brave_unit_tests wiki
    • npm run presubmit wiki, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

@Brandon-T Brandon-T added CI/skip-android Do not run CI builds for Android CI/skip-macos-x64 Do not run CI builds for macOS x64 CI/skip-windows-x64 Do not run CI builds for Windows x64 unused-CI/skip-linux-x64 Do not run CI builds for Linux x64 CI/skip-macos-arm64 Do not run CI builds for macOS arm64 CI/skip-teamcity Do not run builds in TeamCity labels Jan 16, 2025
@Brandon-T Brandon-T self-assigned this Jan 16, 2025
@Brandon-T Brandon-T requested a review from a team as a code owner January 16, 2025 00:30
@kylehickinson
Copy link
Collaborator

CI failing

import Foundation
import os.log

class ZipImporter {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this in Sync/BraveCore/ZipImporter? If its generic lets move it to BraveShared

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment on lines 17 to 18
@MainActor
static func unzip(path: URL) async throws -> URL {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has no reason to be MainActor isolated

Copy link
Contributor Author

@Brandon-T Brandon-T Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does. It calls Brave-Core's await Unzip.unzip(nativeImportPath, toDirectory: nativeDestinationPath) and it crashes iirc, if not on the main-actor with some sequence checker.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then that requirement should be in the core side, not here, otherwise you'd need to remember to always add MainActor isolation when unzipping using this method. If there's a sequence checker requirement then you should be using a stable task runner in the Obj-C++ side since we can't control that aspect from Swift other than forcing the code to run on main

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment on lines 92 to 110
static func uniqueFileName(_ filename: String, folder: URL) async throws -> URL {
let basePath = folder.appending(path: filename)
let fileExtension = basePath.pathExtension
let filenameWithoutExtension =
!fileExtension.isEmpty ? String(filename.dropLast(fileExtension.count + 1)) : filename

var proposedPath = basePath
var count = 0

while await AsyncFileManager.default.fileExists(atPath: proposedPath.path) {
count += 1

let proposedFilenameWithoutExtension = "\(filenameWithoutExtension) (\(count))"
proposedPath = folder.appending(path: proposedFilenameWithoutExtension)
.appending(path: fileExtension)
}

return proposedPath
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be duplicated, we should move it to a shared place

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment on lines 336 to 339
/// URL where temporary files are stored.
public var temporaryDirectory: URL {
fileManager.temporaryDirectory
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be deleted, just access FileManger.default.temporaryDirectory like normal

Comment on lines 189 to 190
public var fileSystemRepresentation: String? {
return self.withUnsafeFileSystemRepresentation { bytes -> String? in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the reasoning for using the withUnsafeFileSystemRepresentation instead of just using absoluteString?

Copy link
Contributor Author

@Brandon-T Brandon-T Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AbsoluteString doesn't strip query parameters or scheme or anything. It's just the full URL as a string representation.
fileSystemRepresentation returns a path always, with no scheme and works better with native code that requires a native file-system path.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why wouldn't you already be dealing with a proper file path here?

Copy link
Contributor Author

@Brandon-T Brandon-T Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the file path we get is from whatever the user selected in the document picker. The url is a file path but it contains the file:/// scheme and I don't want the scheme or the escaping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -18,7 +18,8 @@ extension BrowserViewController: WKDownloadDelegate {
) async -> URL? {

if let httpResponse = response as? HTTPURLResponse {
if httpResponse.mimeType != MIMEType.passbook {
if ![MIMEType.passbook, MIMEType.passbookBundle].contains(httpResponse.mimeType?.lowercased())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually possible for the mime-type stored in URLResponse to be not lowercase for these mimtypes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HTML spec says it's case-insensitive but handling of it depends on the developer. So if I send back TEXT/HTML I'm not sure if it'll be normalized to text/html when received. I'm not sure if iOS will do it.
So I lower-case it anyway.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Chromium major version is behind target branch (132.0.6834.83 vs 133.0.6943.27). Please rebase.

@github-actions github-actions bot added the chromium-version-mismatch The Chromium version on the PR branch does not match the version on the target branch label Jan 27, 2025
@Brandon-T Brandon-T force-pushed the bugfix/PassKitDownloads branch from 87a5449 to 90a20b5 Compare January 27, 2025 18:47
@github-actions github-actions bot removed the chromium-version-mismatch The Chromium version on the PR branch does not match the version on the target branch label Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/skip-android Do not run CI builds for Android CI/skip-macos-arm64 Do not run CI builds for macOS arm64 CI/skip-macos-x64 Do not run CI builds for macOS x64 CI/skip-teamcity Do not run builds in TeamCity CI/skip-windows-x64 Do not run CI builds for Windows x64 needs-security-review unused-CI/skip-linux-x64 Do not run CI builds for Linux x64
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[iOS] - PKPass Bundles cannot be installed
3 participants