-
Notifications
You must be signed in to change notification settings - Fork 114
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
Improve data fetching in Order Details, to avoid I/O performance on the main thread #14999
base: trunk
Are you sure you want to change the base?
Conversation
…oved `feeLinesResultsController` and related logic
…ge, but not present inside the Networking model. Doing this to reduce number of `ResultsController` from `OrderDetailsResultsControllers`: - Update `Networking.generated.swift`, `Models+Copiable.generated.swift`, and `Order.swift` to include `shippingLabels` property in `Order` struct - Update `OrderDetailsResultsControllers.swift` by removing `shippingLabelResultsController` and using `order.shippingLabels` instead - Update various files to incorporate `shippingLabels` property in Order creation and manipulation - Add `Sendable` conformance to `ShippingLabel`, `ShippingLabelAddress`, `ShippingLabelRefund`, `ShippingLabelRefundStatus`, and `ShippingLabelStatus` structs and enums for concurrency safety - Update tests in `OrderDetailsDataSourceTests.swift` to handle `shippingLabels` within `Order` instances
…ch-fetching-in-order-details
|
Thanks for working on this, @pmusolino! Not directly related to this PR: While attempting to test this PR I noticed that the "Add Extension To Store" from the following screen doesn't work. I also noticed that the code is not linked to any action. Code link ![]() Video recording: Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2025-01-29.at.11.13.48.mp4 |
I noticed one more issue that is probably not related to this PR. I have installed WooCommerce Shipping on my JN store, but I still see the "Get WooCommerce Shipping" banner in the Order Details screen. Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2025-01-29.at.11.22.44.mp4I have tried restarting the app (stop and run again from Xcode), but the banner doesn't go away. |
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.
The following issue happens in trunk as well and I don't think this is related to this PR. IMO, this looks related to this CUW post - peaMlT-Yo-p2
After creating a shipping label on my JN store I started facing issues with loading orders.
I tried emptying the orders creating Woo Smooth Generator from my JN store and kept only the order that I manually created from the mobile app. But still the mobile app fails to load that order and shows the following decoding error in logs.
⛔️ Error synchronizing orders: typeMismatch(Swift.Int64, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 4", intValue: 4), CodingKeys(stringValue: "line_items", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "taxes", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "id", intValue: nil)], debugDescription: "Expected to decode Int64 but found a string instead.", underlyingError: nil))
My JN site has the following plugins installed.
Please let me know if you need an invitation to my JN site.
FWIW the "Get WooCommerce Shipping" banner with this install prompt is behind the |
@pmusolino While trying to Refund a shipping label, I found that the "Request refund" button doesn't do anything. |
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.
Quoting the following from the "Testing Information" in the PR description
- Ensure that any changes to the shipping labels (e.g., addition, refund) are immediately reflected in the UI without requiring a manual refresh.
I noticed that the order detail page doesn't reflect the newly purchased shipping label unless I pull down to refresh. Even after I pull to refresh, I see the "Create Shipping Label" button, and it goes away after another pull down to refresh.
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2025-01-30.at.12.13.22.mp4
I filled an issue here about removing the feature flag. |
This doesn't work in |
I tested it by creating the shipping label from the web, and it works; it's visible in the app when opening the order. I also tried creating the shipping label from the app. In this specific case, the refresh does not work as you mentioned, but it also doesn't refresh in the |
@@ -239,6 +245,9 @@ public struct Order: Decodable, Sendable, GeneratedCopiable, GeneratedFakeable { | |||
return OrderAttributionInfo(metaData: allOrderMetaData) | |||
}() | |||
|
|||
// Shipping labels | |||
let shippingLabels = try container.decodeIfPresent([ShippingLabel].self, forKey: .shippingLabels) ?? [] |
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.
👋 @pmusolino Do we receive this shipping_labels
key in orders response? Based on my testing in a Woo store with shipping labels, I don't see it being sent in wc/v3/orders
.
If we do receive the shipping_labels
, should we update the mock JSON and add unit tests to ensure that shipping_labels
are mapped correctly?
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.
Good question, @selanthiraiyan. In ShippingLabelStore
, the method upsertShippingLabels
connects the fetched shipping labels to the specific order, so the order doesn't return specific shipping labels, making it unnecessary to decode the Shipping Labels in the Order model. However, declaring the property (without decoding) in the networking model seems necessary to access shippingLabels
, unless you have another solution in mind.
Yes, we could access the shipping labels from storage, but that's what we're trying to avoid. Do you think I can leave the shippingLabels
property in Order.swift
but remove the decoding? This way, by default, it would be an empty array.
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.
Thanks, @pmusolino! I don't have a solution in mind. But I think we should remove the decoding, as it will be misleading.
I'm tagging @itsmeichigo to check whether she has any other solutions.
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.
Thanks for the ping Sharma!
I think if the key for shipping labels is non-existent in the order response, keeping the property an empty array should be the way to go. There's no need to waste more resources to look for such a key to decode. Please also leave a comment in the code to explain why the value is empty by default, and when it's going to be updated.
However, I'm concerned about this part:
In ShippingLabelStore, the method upsertShippingLabels connects the fetched shipping labels to the specific order
In the order details screen, after syncing shipping labels, we'd need to ensure that the order
in the view model is updated with the fetched label(s), just so they can be displayed on the UI.
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.
Thank you both! I updated the decoding here 85c0115 the comment should be clear enough.
In the order details screen, after syncing shipping labels, we'd need to ensure that the order in the view model is updated with the fetched label(s), just so they can be displayed on the UI.
Yes, this already happens from my testing. If you create or update a shipping label, or open an order detail with an existing shipping label that needs to be fetched remotely, you will see the order detail UI correctly updated.
Version |
- Modify `Order.swift` to initialize `shippingLabels` as an empty array by default. - Update RELEASE-NOTES.txt to correctly place and describe the improved data fetching change in version 21.7.
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.
@pmusolino I cannot see the purchased shipping label in the order detail screen. (Even after multiple pull to refresh attempts)
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2025-02-06.at.11.47.11.mp4
I tested by changing the Xcode scheme Build configuration into "Release" to ensure that we test the shipping labels work in production. (And not the WIP shipping labels project which is behind a feature flag)
![image](https://private-user-images.githubusercontent.com/524475/410319051-f49f4b2f-fddf-482d-9430-68a7a9fe7fd1.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg5NDc2NzQsIm5iZiI6MTczODk0NzM3NCwicGF0aCI6Ii81MjQ0NzUvNDEwMzE5MDUxLWY0OWY0YjJmLWZkZGYtNDgyZC05NDMwLTY4YTdhOWZlN2ZkMS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjA3JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIwN1QxNjU2MTRaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT03ZTBmMjk3ZjRlNjkzNmU0MjBkYjUwZGI5YmZjZmNkZDljNzBmYjVlZWFiOTFmOGY1ZTY3NjE5MThmOTM1YTY3JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.0kuYPLqflwffFb5h2Wes9zwQcZLcAJtGGKwqio2IlCc)
@selanthiraiyan I was blocked from testing that flow because of this new issue #15078 but I believe you didn't encounter this issue. |
@selanthiraiyan it seems to be an issue in ![]() |
👋 @pmusolino - jumping in because I have a question regarding this line:
I also found |
@itsmeichigo Order Refund has not been cleaned up, because the |
@pmusolino This isn't working well for me when I test with opening the order details for an order with a shipping label purchased on the web. Here's the scenario:
In Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-02-07.at.12.07.37.mp4But in this branch, the shipping label shows up and then disappears. It only reappears after I pull to refresh: Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-02-07.at.12.04.21.mp4 |
FWIW I can't reproduce this behavior on my test store. Even if I select "Save for later," I see the purchased shipping label in order details in the app when I test in Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-02-07.at.12.17.45.mp4I tested the same steps in this branch and it also worked for me there. |
Version |
Closes: #14923
Description
We observed that while opening product details, it's easy to see the following warning, generated by multiple reads on storage (Core Data). Also, this issue sometimes generate a lag opening the Order Detail screen.
This warning is occurring because we're making a lot of different fetch requests when loading the details, causing the hang issue.
I solved the issue by removing two fetches from
OrderDetailsResultsControllers
:feeLines
property to return the relationship fromorder.fees
instead, of using a Results Controller to fetch the order fees.shippingLabels
property toOrder
which was connected in Storage with a relationship, but not present inside the Networking model.Networking.generated.swift
,Models+Copiable.generated.swift
, andOrder.swift
to includeshippingLabels
property inOrder
struct.OrderDetailsResultsControllers.swift
by removingshippingLabelResultsController
and usingorder.shippingLabels
instead.shippingLabels
property in Order creation and manipulation.Sendable
conformance toShippingLabel
,ShippingLabelAddress
,ShippingLabelRefund
,ShippingLabelRefundStatus
, andShippingLabelStatus
structs and enums for concurrency safety.OrderDetailsDataSourceTests.swift
to handleshippingLabels
withinOrder
instances.Those were the only relationships with Order. In my opinion, we could potentially improve performance further by handling some fetches externally (e.g., fetching all order statuses). However, the current implementation is structured such that each view/model doesn't have visibility beyond the order itself. While this approach is possible, we need to discuss how deep we want to go with such changes. The current solution, however, does address the I/O problem effectively.
Steps to reproduce
Open multiple times different Order Details. You can notice a purple warning mentioning
Performing 1/0 on the main thread by reading or writing to a database can cause slow launches.
inResultsController
.Testing information
You should not be able anymore to replicate the warning after these changes.
- Ensure the "Create Shipping Label" button is visible when the order is eligible for shipping label creation and has no existing labels.
- Ensure the "Create Shipping Label" button is not visible when the order is eligible but already has shipping labels.
- Ensure the "More" button is visible in the product section when the order is eligible and has no refunded shipping labels.
- Ensure the "More" button is visible in the product section when the order is eligible and has refunded shipping labels.
- Ensure the "More" button is not visible in the product section when the order is not eligible for shipping label creation.
- Ensure that refunded shipping labels are correctly identified and handled, and that the UI reflects this state appropriately.
- Confirm that the order is correctly marked as eligible for shipping label creation based on predefined criteria (e.g., order status, payment status).
- Ensure that any changes to the shipping labels (e.g., addition, refund) are immediately reflected in the UI without requiring a manual refresh.
RELEASE-NOTES.txt
if necessary.Reviewer (or Author, in the case of optional code reviews):
Please make sure these conditions are met before approving the PR, or request changes if the PR needs improvement: