Keeping consistent app state across iOS devices with poor connectivity

Robert Manson
Clutter Developers
Published in
4 min readMar 16, 2019

Clutter operates a fleet of over 500 iOS devices nationally and uses a pre-installed in-house iOS application to facilitate our pickup and delivery operations. The app allows our teams of movers to inventory a customer’s belongings onsite. Having pictures of the items taken on-site allows our customers to access belongings from our account portal and to request specific items to be returned.

When Clutter is at a customer’s location to either pick up or return inventory, our internal iOS application must be able to show the customer an accurate summary of the amount of storage they are currently using. Since this typically happens at a customer’s house we have to make due with poor or no connectivity to the internet.

In order to provide the customer with an invoice that reflects the work done onsite and in-order to track the status of the job remotely, we need to use every opportunity to have the most accurate representation of the job.

Technology

Requests to the Server

Requests to our backend are serialized in a priority queue allowing certain state transactions to be sent in order of creation in the cases where connection to our servers is poor. Local state transitions in an eager manner to reflect the expected outcome on the server.

Realtime Client/Server Syncing

Client/Server state is synchronized using a combination of client to server polling and client to client multipeer connectivity. Polling our backend is limited by WAN availability while multipeer is limited to several meters between the clients, however combining the two approaches has allowed us implement semi-real time updates of an in-progress order.

Server Polling

We create a channel for every active order that can be polled at a set interval for changes made from any one of the clients on the job. The client records the last time it successfully polls and asks for any changes since the last time it checked in.

Multipeer connectivity

We use an Apple feature called MultipeerConnectivity, which allows two or more iPhones to send data to each other using Wi-Fi and Bluetooth. Most people are familiar with this technology through the AirDrop feature on iPhones.

Multipeer was originally designed for games, but it works great for any app that needs to work offline. Since we started using it, the lead mover on a job receives a message each time a member adds or changes and customer item, even without an Internet connection.

Resolving Conflicts

We use an algorithm similar to Google Docs to allow multiple people to add items to an order at the same time. Even if two people change an item’s barcode at nearly the same time, we’ll automatically resolve the conflict in the background.

To resolving conflicts on an in-progress order, we use an eventual consistency model with two types of transforms, tombstoning and last updated.

Last Updated Transform

Either through malicious intent or by accident, it is possible for the local time of an iPhone to diverge (or “drift”) from that of our server. We record clock drift at the beginning of a team members session to establish what server time is. We then use the latest timestamp for a transform to determine which one should apply. An example of this transform in action is as follows: Let’s say one team member categorizes an item as a small box. Another team member then comes along and notices that box is actually a large sized box. She then changes the category of the item and eventually, all the team member’s clients will update to say “large box” for that item. In this scenario is advantageous to have all clients showing the most recent change since that allows going back to correct any mistakes.

Tombstone Transform

Certain types of data should be discarded after one client has deleted or invalidated it. An example of a transform on a customer item such as a box of photos would go as follows. Lets say that we inventory an item but then the customer decides they would not like to have it stored. In this case the team member would delete the item from an active order. In this scenario it would be confusing to the team if the deleted item would suddenly reappear if another team member changes her photos. Therefore any updates to a tombstoned object are ignored.

Conclusion

The powerful multipeer functionality of iOS combined with polling to our backend has allows us to provide accurate invoicing to our customers and allow our team to see an accurate representation of an inprogress order as they work.

--

--