-
Notifications
You must be signed in to change notification settings - Fork 995
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
[Connect] Enable file downloads #4086
[Connect] Enable file downloads #4086
Conversation
🚨 New dead code detected in this PR: ConnectWebView.swift: warning: Function 'showErrorAlert(for:)' is unused
ConnectWebView.swift: warning: Function 'download(decideDestinationUsing:suggestedFilename:)' is unused
ConnectWebView.swift: warning: Function 'download(didFailWithError:resumeData:)' is unused
ConnectWebView.swift: warning: Function 'downloadDidFinish()' is unused
ConnectWebView.swift: warning: Function 'download(_:decideDestinationUsing:suggestedFilename:)' is unused
ConnectWebView.swift: warning: Function 'download(_:didFailWithError:resumeData:)' is unused
ConnectWebView.swift: warning: Function 'downloadDidFinish(_:)' is unused Please remove the dead code before merging. If this is intentional, you can bypass this check by adding the label ℹ️ If this comment appears to be left in error, double check that the flagged code is actually used and/or make sure your branch is up-to-date with |
dfe075c
to
e1fcaf5
Compare
Dead code check flagged false-positive – all the list methods are delegate methods called from WebKit |
@@ -519,7 +519,7 @@ | |||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |||
GCC_WARN_UNUSED_FUNCTION = YES; | |||
GCC_WARN_UNUSED_VARIABLE = YES; | |||
IPHONEOS_DEPLOYMENT_TARGET = 17.5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets us test the SDK on iOS 15 devices
@@ -26,7 +26,7 @@ struct API { | |||
guard let baseUrl = URL(string: baseURL) else { | |||
return .failure(.invalidURL) | |||
} | |||
let url = baseUrl.appending(path: path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appending(path: )
is only available on iOS 16
<constraints> | ||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="tpl-NI-fTA" secondAttribute="trailing" constant="20" id="C34-2d-4Rw"/> | ||
<constraint firstItem="tpl-NI-fTA" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="20" id="HH7-od-x32"/> | ||
<constraint firstItem="tpl-NI-fTA" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="fIw-p1-lqC"/> | ||
</constraints> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Centers the launchscreen text with 20pt horizontal padding
@@ -12,7 +12,6 @@ enum StripeConnectConstants { | |||
/**' | |||
Pages or navigation requests matching any of these hosts will... | |||
- Automatically grant camera permissions | |||
- Accept downloads (TODO MXMOBILE-2485) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're not using allowedHosts for downloads because most of our downloads come from external hosts (e.g. S3)
func showErrorAlert(for error: Error) { | ||
// TODO: MXMOBILE-2491 Log analytic when receiving an eror | ||
debugPrint(error) | ||
|
||
let alert = UIAlertController( | ||
title: nil, | ||
message: NSError.stp_unexpectedErrorMessage(), | ||
preferredStyle: .alert) | ||
presentPopup(alert) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Displays "There was an unexpected error -- try again in a few seconds"
@@ -112,10 +120,11 @@ class ConnectWebViewTests: XCTestCase { | |||
windowFeatures: .init()) | |||
|
|||
XCTAssertNil(webView) | |||
wait(for: [canOpenURLExpectation, openURLExpectation], timeout: 0.1) | |||
wait(for: [canOpenURLExpectation, openURLExpectation], timeout: TestHelpers.defaultTimeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this was always intended to use the default timeout? If not, I can change it back.
/// `window.close()` should close the view | ||
func testWindowCloseDismissesView() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added test coverage for existing functionalty
/// File URL for a downloaded file | ||
var downloadedFile: URL? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mxl-stripe do we need to be robust to potentially handle multiple files that simultaneous download?
The current design only stores one file at a time. If there's multiple downloads that occur simultaneously, we could get some unexpected behavior.
If we need to, we could potentially handle multiple files, but it would take some effort. We'd have to effectively make a queue of downloaded files and wait for them to all finish before showing the preview.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should ever be triggering multiple downloads at the same time. Is it easy to detect if that is happening? I wonder if we could add a metric for that situation and monitor that it's zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should be able to add a metric for this – I added a comment to MXMOBILE-2491 so I remember to do that when adding analytics :-)
// Display a preview of the file to the user | ||
let previewController = QLPreviewController() | ||
previewController.dataSource = self | ||
previewController.modalPresentationStyle = .pageSheet | ||
presentPopup(previewController) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would we want to just present the share sheet directly here rather than having to fix potential bugs involving previewing certain file types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could – let me get feedback from the team what the preference is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we can check if the file is previewable, and if it's not then directly open the share sheet.
https://developer.apple.com/documentation/quicklook/qlpreviewcontroller/canpreview(_:)
Really good call out – from the docs:
Discussion
If the system can’t display an item, but you still attempt to display it, a Quick Look preview controller displays a generic error. Always check whether you can display an item before choosing to do so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to merge this but do a fast-follow PR to address this issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary
Enables file downloads from embedded components
When the file is downloaded, it's previewed in a
QLPreviewController
and allows the user to save the file or open in an app installed on their system.Lowers the min supported OS version of the example app to 15.0, the same as the SDK
This enables us to test on iOS 15 devices.
Adds constraints to the example app Launchscreen so the text is centered on all device sizes
Motivation
https://jira.corp.stripe.com/browse/MXMOBILE-2485
Testing
RPReplay_Final1727924099.MP4