Add support for Watch Connectivity
UberJason opened this issue · 12 comments
This one's definitely an enhancement/feature request. Have you given any thought to adding Watch Connectivity as a supported backend for Ensembles? It would probably behave similarly to Multipeer Connectivity, as it's also a peer-to-peer service that supports sending direct messages and/or files. It also has some niceties like background transfers delivered in order that they were sent.
Not a bad idea, I guess, although not sure there is terribly much advantage over CloudKit. I guess if you have an app that only syncs to the watch it may be better.
We haven’t focused much on the watch, because it is quite underpowered, and you can ask whether a full sync framework, or even Core Data, is a good match. IMO you are probably better to have a simple model on the watch, and just communicate with plists.
That stance may be worth a revisit in the near future. I’ve built a few watch apps and the S3 hardware is quite robust and quick. It handles Core Data just great. The watch is held back more by limitations in WatchKit these days than hardware performance, but that’s more a UI framework issue. (Example: the watch is slow to load a table of Core Data objects, but when I profiled it in Instruments, the CD fetch was quick; the bottleneck was actually the WatchKit implementation of the table.)
I've also noticed that the watch's networking can be slow because it's still preferring to delegate networking to the phone and stream the results over Bluetooth (putting the phone on airplane mode makes the watch's networking quicker!). This would be another potential benefit to syncing over Watch Connectivity, as the phone can send changes to the watch directly rather than via CloudKit (where the watch would reach back to the phone to talk to CloudKit anyway).
I guess one advantage of CloudKit is that with the newer watches that work over mobile, they can sync without the iPhone. You can already do this, of course. Ensembles 2 has a watchOS framework which will work with CloudKit.
I'd also love to see WatchConnectivity as a backend. I'd want to use in addition to the CloudKit backend on watchOS (does Ensembles support multiple backends at the same time?). CloudKit sync is quite slow on the watch, which also means watchOS rarely will do it in the background. Being able to use WatchConnectivity to wake up the watch app and push over the latest changes from the phone would be awesome.
I haven't used the MultipeerConnectivity backend, but I'd imagine WatchConnectivity would be similar (no server, etc.)
WatchConnectivity
is just for small amounts of data and when and if your data is delivered, is based on many factors.
After a few years with working with it: It's just too unreliable.
Rebuild my watch app using a CloudKit backend. Faster and stable. I guess Apple does not invest more energy in the framework, since watches became independent…
WatchConnectivity
is just for small amounts of data and when and if your data is delivered, is based on many factors.After a few years with working with it: It's just too unreliable.
Rebuild my watch app using a CloudKit backend. Faster and stable. I guess Apple does not invest more energy in the framework, since watches became independent…
My app used WatchConnectivity for years so I'm well aware of its shortcomings. I've just moved my watch app to use CloudKit+Ensembles, which is way more reliable but is not faster. It seems especially slow for some users because changes are rarely synced in the background, and so you have to wait for it to sync every time you open the app. For users who were used to being able to quickly switch from the iPhone app to the Watch app, that's a bummer.
If you've got any tips for faster syncing on watchOS I'm all ears!
I was just going to chime in and also say that I absolutely believe CloudKit is more reliable, but I would have a hard time believing it's faster. I found WatchConnectivity both reliable and fast if you've done all the million gotchas correctly, and the user favors your app (e.g. it's in the Dock or has a watch face complication). My app used and still uses WatchConnectivity and I've thought of migrating to CloudKit, so to hear that it's still slow and not background is disappointing.
I haven't taken the time to think this all the way through, but given the amount of control that Ensembles gives you around global identifiers for sync, I wonder if there's a way to build the best of both worlds - use CloudKit for sync, but also send changes across WatchConnectivity directly, making sure to use the same global identifier to help the system not accidentally duplicate changes?
I should say - the amount of control Ensembles gives you around global identifiers, as well as the number of delegate callbacks available to help manage conflicts and collisions - together, it seems like it would be workable to build a system that primarily uses CloudKit but also can handle direct changes via WatchConnectivity.
I haven't taken the time to think this all the way through, but given the amount of control that Ensembles gives you around global identifiers for sync, I wonder if there's a way to build the best of both worlds - use CloudKit for sync, but also send changes across WatchConnectivity directly, making sure to use the same global identifier to help the system not accidentally duplicate changes?
That's what I've been pondering. Basically a way to try to send the latest changes via WatchConnectivity as well as CloudKit. If the watch gets the changes right away via WC, great; if not, it'll get them eventually via CK. But I don't know if Ensembles lets us combine backends like that…
If not, could you consider rolling your own, simple manual sync engine for situations like these? My app actually doesn't use Ensembles for WatchConnectivity, so I just rolled my own. My data model was straightforward, though.
I don't have much experience with the watch. I did play with it using the LLVS experimental store, but not with Ensembles.
I'm not sure supporting WC would help that much. The problem may not even be so much in the data transfer. It could be that CloudKit is quite fast, but that the watch then has to catch up with the sync, which might involve not just the data the user wants to edit right now, but other changes since the last time the app was started. In other words, Core Data itself may be just as much a factor in the slowness.
Don't know what you can really do about it, other than perhaps consider using a slimmed down separate store for the watch. A simpler model, and less data. Ensembles would sync that to the main app, which would keep it populated with its larger database.
And, of course, you can just choose to go with something completely different for the watch. A simple plist you send over, or something like that. It depends how much data it needs, I guess. If it doesn't need the full database, syncing the full database with Ensembles may be overkill.
Just to mention, I think we had a very similar conversation two years ago (at the top of this thread/issue), and Core Data was already quite fast on a Series 3 back then - the S5 is way faster now. I don’t think the watch should be considered underpowered anymore.