I’m getting reports for some new users that Voice in a Can (Alexa on your Apple Watch, Vision Pro, Mac and iPhone) is showing an Amazon error Key master exception and when I look at the logs I indeed see this:

didReceiveResponse: http code: 500 and internalServerError for E32C00D1-EF8F-4DDE-B9DE-4A4EBB7ACCC3
Key master exception

Amazon have also announced that they will not support new apps/devices using the Alexa Voice Service (all the AVS documentation is gone) … so even if I can fix this I think the writing is on the wall … so it seems like now might be the best time to pull the plug, unless Amazon tells me otherwise.

I first launched it in 2018, and its been fun and done well. All good things …

The story of Voice in a Can

A fun side-project

lTea

It started with a cup of tea. Evernote, the company I’d been working at for the previous five years was undergoing “changes”. I’d been let go, as had Phil Libin, Evernote’s CEO. We met at the Samovar Tea Lounge in San Fransisco, and were bouncing ideas around. This was in 2015.

Phil mentioned this new thing that was starting to get momentum … it was called the Amazon Echo. He ordered one for me there and then from Amazon, and the next day I gave him cash, and he gave me a new Echo to take home to Switzerland.

It was rough at first, since Switzerland was not one of the supported countries: to get the correct time I had to claim I was in American Samoa!

But the family loved it, which doesn’t always happen with new tech.

My daily commute

I started looking behind the scenes, and found out there was an Alexa Voice Service web API which apps could call … interesting. What if I could combine my passion for wearables (including the Apple Watch) and Alexa?

I first started coding this app on the train every day, commuting to my day job. Its always been a side-project.

I initially built it in C# using Xamarin (the call of async/await was strong), on the 12” MacBook Adorable. I remember being jet-lagged on holiday in Hawaii, programming away in the middle of the night.

I got it working on the iPhone first, and then ported it to the Apple Watch. And it was slow. So slow. Nevertheless Tom Warren at the Verge picked on the launch and it it made quite the splash (that’s 1.50K not 150K on the left).

launch day sales spike

Eventually the watch hardware got faster, and the app became usable.

Things get serious

I completed a rite of passage when I received an email from an Amazon lawyer asking me to confirm that I was following their rules (streaming directly from the microphone and not storing audio etc), which was a little scary but ended with the lawyer mentioning the app was cool!

My biggest surprise, and what took it from a fun side-project to something more serious was obvious in retrospect: People with vision issues or disabilities really liked the app, and really used/needed the app.

...Thank you for the great support    
I am 82 years old with 25  years in the USAF. 
I am now fighting Stage 4 Prostrate Cancer & stage 3 Melanoma     I'm going to beat it or die trying   
Ha   I am not a wiz but I have got all the smart devices  to help me as the cancer gets worse  
So far I have 29 smart devices installed which I can control with my voice, IPhone, IPad and 
laptop and now apple watch thanks to you>>    11 Lights, 4 Fans, 4 cameras,
August Lock, Nest thermostat, Ring Doorbell pro, ECHO Dots & Show and a few other things 
all controlled thru Amazon Alexa from anyplace....  VOICE IN A CAN
is a great  APP    I don't know what I did but got it working on my Apple Watch 3. 
It allows me to voice control all 29 smart devices from my WATCH...  
Thanks😎

All change

I released Voice in a Can for almost all the Xamarin platforms:

  • Tizen (Samsung Watches)
  • iPhone
  • Android
  • Mac
  • Xbox
  • Windows
  • Apple Watch

However Microsoft acquired Xamarin (yay!) and then announced they would not support the Apple Watch for Xamarin any more (boo!), so I had to move on from Xamarin.

Most of my sales were on the Apple Platforms, so I re-wrote (From C# to Swift: some hints for those considering this path) the whole thing in Swift and SwiftUI, learning a lot on way. This gave me the opportunity to add support for the Alexa Presentation Language (APL): Rendering the Alexa Presentation Language in SwiftUI (with bonus Moose).

macOS/StartListeningAppIntent.swift
macOS/AppDelegate.swift
macOS/AppleWatchAlexaApp.swift
iOSTests/iOSTests.swift
iOSWidget/iOSWidget.swift
iOSWidget/iOSWidgetBundle.swift
Shared/UI/MainTabView.swift
Shared/UI/Settings/AboutView.swift
Shared/UI/Settings/BugReportView.watch.swift
Shared/UI/Settings/SettingsTabView.watchOS.swift
Shared/UI/Settings/SettingsTabView.macOS.swift
Shared/UI/Settings/MailView.swift
Shared/UI/Settings/LanguagePicker.swift
Shared/UI/Settings/BugReportView.ios.swift
Shared/UI/Settings/PopupView.swift
Shared/UI/Settings/BugReportView.mac.swift
Shared/UI/Settings/SettingsTabView.iOS.swift
Shared/UI/AplHostView.swift
Shared/UI/LoggedInView.iOS.swift
Shared/UI/SystemFeedbackView.swift
Shared/UI/TestApl/OpenThePodBayDoors.swift
Shared/UI/TestApl/HelloWorld.swift
Shared/UI/TestApl/NoTimersSet.swift
Shared/UI/TestApl/AplTimer.swift
Shared/UI/TestApl/PagerKittens.swift
Shared/UI/TestApl/ShowMeMyShoppingList.swift
Shared/UI/TestApl/TestAplMain.swift
Shared/UI/TestApl/Weather.swift
Shared/UI/TestApl/TestTextField.swift
Shared/UI/TestApl/AutoscrollText.swift
Shared/UI/LoggedInView.macOS.swift
Shared/UI/LoginView.swift
Shared/UI/LinkKind.swift
Shared/UI/WebImage.swift
Shared/UI/Initializer.swift
Shared/UI/BackButton.swift
Shared/UI/LegacyAplAndTemplateView.swift
Shared/UI/LoginWithAmazonCodeView.swift
Shared/UI/ContentView.swift
Shared/UI/LoggedInView.watchOS.swift
Shared/ProductInfo.swift
Shared/Logable.swift
Shared/AtomicInteger.swift
Shared/apl/AplComponentWrapper.swift
Shared/apl/enums/AplObjectType.swift
Shared/apl/enums/AplPointerEventType.swift
Shared/apl/enums/AplGradientProperty.swift
Shared/apl/enums/AplDisplay.swift
Shared/apl/enums/AplFontStyle.swift
Shared/apl/enums/AplGraphicElementType.swift
Shared/apl/enums/AplScrollDirection.swift
Shared/apl/enums/AplPropertyKey.swift
Shared/apl/enums/AplEventType.swift
Shared/apl/enums/AplGraphicPropertyKey.swift
Shared/apl/enums/AplSpanType.swift
Shared/apl/enums/AplComponentType.swift
Shared/apl/enums/AplTextAlignVertical.swift
Shared/apl/enums/AplImageScale.swift
Shared/apl/enums/AplEventProperty.swift
Shared/apl/enums/AplUpdateType.swift
Shared/apl/enums/AplTextAlign.swift
Shared/apl/enums/AplGraphicScale.swift
Shared/apl/AplGraphic+Definitions.swift
Shared/apl/components/AplEditTextView.swift
Shared/apl/components/AplVectorGraphicView.swift
Shared/apl/components/AplFrameView.swift
Shared/apl/components/AplContainerView.swift
Shared/apl/components/AplSequenceView.swift
Shared/apl/components/AplScrollView.swift
Shared/apl/components/AplTextView.swift
Shared/apl/components/AplGraphicElementView.swift
Shared/apl/components/AplComponentProperties.swift
Shared/apl/components/AplPagerView.swift
Shared/apl/components/AplTouchWrapperView.swift
Shared/apl/components/AplImageView.swift
Shared/apl/AplView.swift
Shared/apl/AplLoader.swift
Shared/apl/ColorDebugger.swift
Shared/apl/JsonData.swift
Shared/apl/SvgVectorView.swift
Shared/apl/AplComponentView.swift
Shared/DirectiveProcessor.swift
Shared/UserDefaultStorage.swift
Shared/Localized.swift
Shared/KeyStore.swift
Shared/SwiftWebVTT/HTMLCharacterReferences.swift
Shared/SwiftWebVTT/Deduplication.swift
Shared/SwiftWebVTT/WebVTTParser.swift
Shared/SwiftWebVTT/Extensions.swift
Shared/SwiftWebVTT/Scanner.swift
Shared/SwiftWebVTT/WebVTT.swift
Shared/Providers/MicrophoneProvider.swift
Shared/Providers/AudioPlaybackProvider.swift
Shared/Providers/Real/AVCaptureSessionMicrophoneProvider.swift
Shared/Providers/Real/DeviceMicrophoneProvider.swift
Shared/Providers/Real/NetworkInteraction.swift
Shared/Providers/Real/DeviceLocationProvider.swift
Shared/Providers/Real/AVAudioPlayerPlaybackProvider.swift
Shared/Providers/GuidStringProvider.swift
Shared/Providers/KeyStoreProvider.swift
Shared/Providers/LocationProvider.swift
Shared/Providers/NetworkProvider.swift
Shared/StateCoordinator.swift
Shared/Extensions/InputStream+Extensions.swift
Shared/Extensions/DispatchQueue+extensions.swift
Shared/Extensions/String+Extensions.swift
Shared/Extensions/OutputStream+Extensions.swift
Shared/Extensions/Color+Extensions.swift
Shared/Extensions/Data+Extensions.swift
Shared/Extensions/ISO8601DateFormatter+Extensions.swift
Shared/UpChannel.swift
Shared/PropertiesMigrator.swift
Shared/Settings.swift
Shared/ResponseParser.swift
Shared/Downchannel.swift
Shared/HttpStatus.swift
Shared/Login/LoginWithAmazonCode.swift
Shared/Login/LoginWithAmazonSDK.swift
Shared/Login/LWABase.swift
Shared/Generation.swift
Shared/Interfaces/AudioPlayer.swift
Shared/Interfaces/SpeechRecognizer.swift
Shared/Interfaces/Alexa.ApiGateway.swift
Shared/Interfaces/AudioPlayerDefinitions.swift
Shared/Interfaces/Alexa.Presentation.APL.Video.swift
Shared/Interfaces/Speaker.swift
Shared/Interfaces/Alexa.Display.Window.swift
Shared/Interfaces/InterfaceBase.swift
Shared/Interfaces/EventMessage.swift
Shared/Interfaces/TextInterface.swift
Shared/Interfaces/Geolocation.swift
Shared/Interfaces/TemplateRuntime.swift
Shared/Interfaces/InteractionModel.swift
Shared/Interfaces/PlaybackController.swift
Shared/Interfaces/Notifications.swift
Shared/Interfaces/Alerts.swift
Shared/Interfaces/Context.swift
Shared/Interfaces/AudioPlayerStateMachine.swift
Shared/Interfaces/System.swift
Shared/Interfaces/SpeechSynthesizer.swift
Shared/Interfaces/Alexa.Discovery.swift
Shared/Interfaces/AlexaInterface.swift
Shared/Interfaces/Alexa.InteractionMode.swift
Shared/Interfaces/Alexa.Display.swift
Shared/Interfaces/MessageIdHeader.swift
Shared/Interfaces/Alexa.Presentation.APL.swift
WatchOS Extension/ComplicationController.swift
WatchOS Extension/ExtensionDelegate.swift
WatchOS Extension/AppleWatchAlexaApp.swift
iOS/ar/AugmentedContentView.swift
iOS/AppleWatchAlexaApp.swift
visionOS/OnboardingView.swift
visionOS/ContentView.swift
visionOS/AppleWatchAlexaApp.swift
watchOSWidget/WidgetKind.swift
watchOSWidget/watchOSWidget.swift

App Store reviews were mixed with many people loving it, but some not so much. I wrote a post about dealing with 1 star reviews: Not even worth one star: Reacting constructively to App Store reviews

reviews

There at Launch Day for the Apple Vision Pro

More recently I released Voice in a Can for the Apple Vision Pro, being one of the first 600 apps available on launch day.

I even got (half) an icon shown on stage at Apple’s 2024 World Wide Developer Conference (top right). launch day sales spike

All good things…

It’s a little sad to be shutting it down, and if Amazon came to me and asked me to continue supporting Alexa on the Apple Watch and Apple Vision Pro, via Voice in a Can, I’d happily say yes, however I suspect that their focus is elsewhere.

On to new things!