Skip to content

Update ProductsRemote to load products with async/throws network methods to parse response in a background thread #15781

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

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from

Conversation

jaclync
Copy link
Contributor

@jaclync jaclync commented Jun 19, 2025

Closes WOOMOB-605

Just one reviewer is required.

Why

In most of the network calls except for the enqueue<M: Mapper>(_ request: Request, mapper: M) async throws -> M.Output version, the response is parsed by a mapper on the main thread. When the response size is large like in the support case in WOOMOB-607 with a large amount of product metadata, the UI could become unresponsive. This PR updates the remaining ProductsRemote functions that return a product list from the previous Combine/completion block based enqueue method to the enqueue<M: Mapper>(_ request: Request, mapper: M) async throws method, so that the response parsing along with other network related tasks are performed in the background thread. There are already several use cases of enqueue<M: Mapper>(_ request: Request, mapper: M) async throws for a while that we can consider it stable.

I'm prioritizing network calls for entities with a potentially large amount of data like from metadata (Product and Order) or some collection fields.

Description

Refactoring to async/await in ProductsRemote:

  • Updated ProductsRemoteProtocol method signatures to replace completion handlers with async throws for methods like loadProducts, searchProducts, and searchProductsBySKU. [1] [2]
  • Refactored ProductsRemote implementation to use async throws and removed completion handler logic. Simplified error handling and return values, such as returning an empty array directly for empty product IDs. [1] [2]

Test case updates:

  • Updated test cases in ProductsRemoteTests to use async/await for methods like loadProducts, searchProducts, and searchProductsBySKU. Removed completion-based test logic and added proper error handling for async tests. [1] [2]

ProductStore updates:

  • Refactored dependent code in ProductStore to use async/await when interacting with ProductsRemote. This includes replacing completion handlers with Task blocks and handling results in a streamlined manner. Store action completion blocks are called on the main thread, while await methods can be in a background thread. [1] [2]

Mapper simplification:

  • Replaced ProductListMapper with a generic ListMapper<Product> in several methods to simplify the mapping logic for product-related API responses. This mapper is no longer used and will be removed in a future PR. [1] [2]

Steps to reproduce

Prerequisite: put a breakpoint in ListMapper decode calls in Xcode; the store should have a few products and at least one review

  • Launch the app
  • In the My store tab, add the "Most recent reviews" card if needed --> the breakpoint in the prerequisite should be triggered by ProductStore.retrieveProducts in a background thread. after the breakpoint, the corresponding products should be loaded correctly as before
  • Go to the Products tab and search for products --> the breakpoint in the prerequisite should be triggered by ProductStore.searchProducts in a background thread. after the breakpoint, the matching products should be loaded correctly as before
  • Tap on the SKU tab and search for products by sku --> the breakpoint in the prerequisite should be triggered by ProductStore.searchProducts in a background thread. after the breakpoint, the matching products should be loaded correctly as before
  • Go to the Orders tab and tap on an order where some products haven't been loaded --> the breakpoint in the prerequisite should be triggered by ProductStore.requestMissingProducts in a background thread. after the breakpoint, the matching products should be loaded correctly as before

Testing information

I tested above use cases on an iOS 18.5 iPad device.


  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

@jaclync jaclync added this to the 22.7 milestone Jun 19, 2025
@jaclync jaclync added the type: task An internally driven task. label Jun 19, 2025
@jaclync jaclync changed the title Update ProductsRemote to load products with async/throws network call so that data parsing is in a background thread Update ProductsRemote to load products with async/throws network methods to parse response in a background thread Jun 19, 2025
@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Jun 19, 2025

App Icon📲 You can test the changes from this Pull Request in WooCommerce iOS Prototype by scanning the QR code below to install the corresponding build.

App NameWooCommerce iOS Prototype
Build Number30576
VersionPR #15781
Bundle IDcom.automattic.alpha.woocommerce
Commit9439f95
Installation URL0ljggd80d7m2g
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@jaclync jaclync marked this pull request as ready for review June 19, 2025 01:50
@staskus staskus self-assigned this Jun 19, 2025
Copy link
Contributor

@staskus staskus left a comment

Choose a reason for hiding this comment

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

Thank you. The changes look good 👍

I can confirm that parsing happens in the background thread while the completion is executed on the main thread. The affected functionality continues to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: task An internally driven task.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants