OnewheelCommunityEdition / OWCE_App

GNU General Public License v3.0
114 stars 30 forks source link

Initial support for OWCE Watch app #63

Closed koa28 closed 3 years ago

koa28 commented 3 years ago

Adding watch app support. This first version does the following:

I've also included a documentation page to walk through how the code is implemented.

koa28 commented 3 years ago

@beeradmoore I've created the PR for this first version of the watch app, you can decide how / when / where (or even if :) ) you want to merge into the main code. Let me know if you have any comments, happy to address them as well.

beeradmoore commented 3 years ago

@koa28 it's not an if, its just a when :) Still waiting for time to review.

TestFlight app expires in 26 days. I'll try do it before then to include in the next release (ideally I'll find time this week to review and merge)

beeradmoore commented 3 years ago

@koa28 , I generated certs for WatchKit and WatchKit Extension projects and tried to deploy a debug build. I have auto watch app install turned off so I have to hit the button to manually install but it fails to install.

System log of my phone says

Desc Failed to verify code signature of /var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.eq7kZE/extracted/Payload/OWCEWatchOSWatchOSApp.app : 0xe8008016 (The executable was signed with invalid entitlements.))"

But as far as I know the app doesn't have any entitlements. Did you have to do anything different when generating the provisioning profiles to test?

koa28 commented 3 years ago

Hmm, that's strange. I also have auto watch app install turned off, and manually re-install my watch app every time I upload a new binary.

I used wildcards to specify my provisioning profile, eg "foo.bar.owce*" which will cover "foo.bar.owce" and "foo.bar.owce.watchkitapp" etc... maybe that helped because the same cert is used for all 3 apps. At the very least, do all 3 certs that you created match the exact same developer and team?

Did you also check that the Bundle Signing dialog in the Visual Studio Project Options match the exact same team for all 3 projects -- (iOS, WatchApp and WatchKitExtension)?

Which version / OS of the Watch do you have?

Lastly, I've done weird things like reboot the Mac, Phone and Watch which resolves some things, presumably cos some pieces of info are cached which could include things related to signing profiles.

koa28 commented 3 years ago

Oh, and you might need to accept the new provisioning profiles on your phone, I believe under Settings -> General -> Profiles and Device Management

beeradmoore commented 3 years ago

Reboot didn't help. I created wildcard AppID + provisioning profile, build didn't work. I suspected it was using my old provisioning profiles so I set it to use the new ones and now build worked. No idea wildcard works fine and the other ones didn't. When I had checked with my old ones it was on auto and there was only 1 available for each project. Oh well.

Watch is Series 6 (44mm I think) running 7.6.1, iPhone is a 11 Pro Max running 14.7.1.

Haven't been out to ride, but so far it looks like its going to work perfectly fine for an initial release.

One thing I would like to see added is to add a message to the watch of "please connect your phone to your board to continue". Just because a lot of people will launch the app on their watch and question how do they connect it to their board. I don't mind if you do that, or if I slap it in before next beta in the next few weeks.

Also not critical would be somewhere to mention how to keep the app running in the foreground on the watch. It doesn't go backgrounded for me but I think the default setting is to always return to your watchface after sleep.

Complication icon is clipped around the edges for me. Do we just need fixed icons added for that?

Good job on it, can't wait to try it out and then get it into everyone else's hands.. .err.. wrists :P

koa28 commented 3 years ago

1) Regarding adding a message to connect via phone, I think the simplest way might be to have a message at the top of the watch screen that is otherwise hidden when the board is connected to the phone app. If we want an entire screen for this message, it needs to have its own controller and I'd rather not switch between controllers in this first cut. As for the watch app determining whether the board is connected or not, one easiest way is probably to to check whether the session is "WCSession.Reachable" (via WCSessionManager.cs), when the watch app wakes up, which means the watch app is active while the phone app is not. Other than that, if the session is active, the watch app already requests for the phone to send it the latest data whenever it wakes up, so it could have a timer where if the phone doesn't respond within a certain time, it can display the message.

I'll try and find some time this week to take a look, but if you have time and want to take a stab at it, more than happy for you to do so.

2) How do you keep it running in the foreground? I set it for some apps but forgot how and mine doesn't stay in the foreground (the complication is on the face, so I get back to the app easily). And where would you put this tip (assuming we stick with one screen for initial version)? Like a block of text at the bottom of the watch screen?

3) For the Complication icons, it's referenced in ComplicationController.cs under the WatchOSExtension project, and uses the "OWCELogo" bundle under Media.xcassets. We might need icons of the appropriate size. My watch is the Watch Series 6 40mm. Sorry, not as familiar with how graphics sizing works in iOS / WatchOS.

beeradmoore commented 3 years ago

All in all, it's beta and I am happy for us to push it to general public as it is (once I go for a ride and see it). TestFlight expires in 13 days so if none of these things can be fixed that's fine, we can send it and deal with it later.

For 1., if we can show/hide that message can we just show/hide the other content to keep it all in the same controller?

For 2., In the current watchOS version its Settings > General > Wake Screen > Return to clock: After 1 hour, on iPhone its pretty much the same but in the watch app. I think it used to have a different name/setting.. Mine was on 2minutes and just tested it going to sleep (or at least it goes dimmed with time over the top), and after 1min 45sec I raised wrist and it was still running. Leaving it 2mins after that when I raise it disappears.

It's difficult though. Generally I'd like all apps to disappear after 2 minutes, but I'd want OWCE to show until I manually hide it. So asking users to bump this to 1h may bother them when using other apps.

Info should probably go in app so it's easier to read/understand.

I think if the app records a ride as a workout it allows it to stay in the foreground without user having to go into app settings. It all depends if users want "Open skateboard" or "open other" in their workout history each time they ride.

For 3., I don't know it either :P. Ill look into it and attach correct images to go into the PR.

For future changes I wonder how useable 3 of the small complications would be, speed, battery%, and voltage. All in their own colour. Maybe the medium/large can display multiple of these values. I don't know the limits of how often we can update them though. But if they can be updated regularly I could see a use case of keeping my normal watchface for everyday use and then swiping sideways to go to my OW watchface which auto displays info from OWCE.

koa28 commented 3 years ago

For 1, yes, we can show / hide the message / content to keep within the same controller. I made some changes locally that does exactly that. Will package into a commit into this PR after testing a bit more.

koa28 commented 3 years ago

I added a new commit that shows the "Connect phone to board" message. Tested briefly and seems to work reasonably well.

koa28 commented 3 years ago

One area that the watch won't show a "Connect via phone" message is when you turn off the board. The problem is not just with the watch, but with the app itself -- it seems to remain in a limbo state where it's showing stale values, until you choose "Connect another Onewheel". In this case, the watch will also show the same stale values cos the app thinks it's still connected to the board (and therefore continuing to respond to the watch's request for updates). Maybe the app itself should disconnect and pop out into the board list page when the board is turned off?

beeradmoore commented 3 years ago

App is meant to go into a "reconnecting" state, mainly useful for the 4208 boards that keep losing connection with iPhones. But I guess also useful if you are on a group ride and walk into a shop while friends mind your board. IMO it should only try reconnect for a set amount of time or a set number of events before it disconnects.

The reconnecting prompt should have a disconnect button to force disconnect.

I don't recall if I have that code stashed somewhere or if it is implemented with no actual UI. But when reconnecting is a thing we should reflect it in the watch app. But that is a problem for another day.

beeradmoore commented 3 years ago

Touching base about provisioning profiles again after I had troubles the first time. I went through through what apple recommends here

The WatchKit app must have the format [Bundle ID].watchkitapp, and the WatchKit extension must have the format [Bundle ID].watchkitextension.

But while trying to compile it gave me errors saying that the extension bundle ID does not create the watch app bundle as a suffix. I created a test app in Xcode and added WatchApp target and let it create the bundle IDs. It generated:

Went and updated OWCE to follow this naming convention only to find you had it named correctly.

I found an app that allowed me to delete provisioning profiles, so I cleared out all the OWCE ones, generated new ones, bingo bango the app installed perfectly fine on the watch.

No idea what the problem was there. 🤷‍♂️