I know according to Apple Docs that didRecieveUserInfo doesn't get called immediately when running on the Watch. It might take a few minutes or more to ever get called in the background.
So how can you test this in the Simulator (without having to sit and wait there for X minutes after you run the Watch app)?
My app is set up to use didReceiveUserInfo, and it works off and on, but there is nothing predictable when it will run, so it makes testing and debugging very frustrating. Has anyone else run into this, or are able to shed some light?
This will likely be dependent on how your phone app sends data to the watch, but have you tried launching the phone app in the iPhone simulator after your watch app starts up?
In the app I'm working on, my iPhone app sends some data to the watch shortly after it launches. If I begin debugging my watch app from Xcode, after the watch app launches, I then switch over to the iPhone simulator, and manually start my iOS app. Soon after, the didReceiveUserInfo methods are called back in the watch app.
Related
So, I am trying to use the oppertunity when my Watchkit complication calls requestUpdateDidBegin() to use sendMessage() to wake my iOS app and cause it to calculate complication data and use transferCurrentComplicationUserInfo() to update the complication. I call sendMessage() from the extension delegate. I am experiencing mixed luck with this actually reaching the iOS app. Even with my iPhone next to the watch the performance varies. One time I built my app to my phone and it successfully delivered over 30 updates to my complication through sendMessage() and transferCurrentComplicationUserInfo(), over the course of two days. I then uninstalled the app from the watch using the watch app, and then reinstalled it from the watch app (So absolutly no code or build changes) and it stopped working! I suspect there is clearly some bugs and unreliability with calling sendMessage(). Is anyone else finding this, is there any workarounds? How can I wake my iPhone app from when the complication controller calls requestUpdateDidBegin()?
I don't believe there is any guarantee you can wake the iPhone from the watch. If you need to update with data from the phone, you are better to schedule the updates on the iPhone app and then push the updated data from the phone. You'll probably need to enable a background mode on the iPhone app for this to work (location services, background data transfer, depending on your data type.)
(As posted here https://forums.developer.apple.com/thread/26934)
I am struggling with debugging my WatchKit Extension/App on a real Apple Watch. Debugging both the iPhone App and the WatchKit Extension using the simulator the simulator is not problem:
Select the WatchKit App Profile and run in Simulator ==> App is launched on in Watch Simulator and I can use breakpoints in the Extension code to debug.
To debug the iPhone app as well I launch the app in the simulator and attach the debugger manually ==> I can use breakpoints in the iPhone Code to debug.
It is no problem to observe both the work of the iPhone app and the watch app. At least not in the simulator.
I would like to do the same thing on a real Apple Watch. But when I select the WatchKit App Profile and my real iPhone (instead of the Simulator) and click on "Run" nothing happens. This means Xcode seems to build and start the app but nothing happens on the devices. The status field in Xcode shows:
Building MyApp WatchKit App: MyApp WatchKit Extension
Building MyApp WatchKit App: Finishing...
Running MyApp on My iPhone 6
This is all. No debug Window, breakpoints are ignored or do not work and the app is not launched neither on the iPhone or on the Apple Watch.
I found other questions about problems with debugging on real devices (e.g. here) but they all deal with installation and signing issues. In my case both the iPhone App and the WatchKit App are installed without any problem. When I click the app icon on the Watch I can start and use the app. Problem is that I cannot debug this process.
Why do I need to debug the process on real devices? Well there is one thing I cannot test using the simulator: What happens when the Watch App tries to contact the iPhone app using openParentApplication:reply: when the iPhone app is not already running? This works perfectly in the simulator but on real devices the Watch Apps seems to get no reply from the iPhone app and simply waits forever.
I already found hints to solve this but without being able to debug the Watch App and to see how the code is executed I cannot be sure what is going on...
thank you for your answers. I finally managed to get the debugging running (most of the time) on my real Apple Watch. However it is quite cumbersome and not very reliable. There is not enough space in the comments so I will use this answer to describe my solution. Maybe it is help full to other:
Make sure, the App on your Watch is not running (as BalestraPatrick described). Launch the app and hold the side button a few seconds to bring up the "Turn off your Watch" dialog. Hold the side button for another few seconds to close the app and to return to the Watch homescreen.
Make sure the iPhone is not locked.
Select the WatchKit App target and your real iPhone and run the project.
Running the Watch App resulted quite often in an error SPErrorInvalidBundleNoGizmoBinaryMessage. Re-starting Xcode and cleaning both the Watch App and the App target solved this.
If the build of the Watch App succeed there will be a short message in Xcode but nothing on your iPhone or Watch. If you have made changes to the Watch App it will take a few seconds to refresh the app on the Watch. This is indicated by the progress-circle overlay over the app icon. If you made no changes ore once the app has been transfered: Launch the watch app manually by tapping the icon. There will be no automatic launch.
In most cases Xcode will recognize the app launch and attach its debugger to it. This will allow to use breakpoints, inspect the code, etc.
In my case I whanted to inspect how the iPhone App handles the application:handleWatchKitExtensionRequest:reply: call when the app was not active before. This is important because this cannot be done using the simulator. If the app takes to long to handle the request the Watch will receive no valid response.
After following the steps described above Xcode is only attached the watch app and will not hold on breakpoints in the iPhone app code. To do this, one has to manually attach the Debugger to the iPhone app process that is started when the watch app sends its call.
To be able to attach the debugger I added a delay to the apps main function: [NSThread sleepForTimeInterval:5]:
Select function in Watch App that will start the call to the iPhone App
The iPhone App will be launched in background. The delays gives you 5 seconds to attach the debugger.
Choose Debug\Attach To Process\Likely Targes\Your iPhone Appin Xcode to attach the debugger.
After the 5 seconds delay the process will continue and you will be able to use breakpoints in your iPhone app code as well.
Do not forget do remove the delay code when you finished testing :-)
NOTE:
You will not be able to see NSLog output (or any console output at all) from the iPhone App since attaching the debugger does NOT re-route the console output.
Happy testing with this awesome new Apple product :-P
I am having the same kind of issue but to improve a little bit the debugging experience I usually restart my devices a few times. Try to restart your Apple Watch or your iPhone.
Before launching your app from Xcode, make sure that the app is completely closed on your Apple Watch (not stuck in the loading screen for example). To do that, you have to force close the app: enter your app, keep the side button pressed until the menu to turn off the watch appears, then press the same side button for a few more seconds until the watch will go back to the homescreen and force close your app.
Now you can try to build and run the app from Xcode and it should work more reliably.
watchOS 3+:
The force quit is done by pressing and holding the side button (the button just below the Digital Crown) until the shutdown screen appears, and then
let go of the side button, then press and hold the Digital Crown.
Here's a technique that seems to be be the most reliable for me, even though it still only works about 25% of the time (Xcode 7 beta 4, 7A165t):
Run the phone target in debug (on your actual iPhone of course)
While the iPhone app is still running, switch to the watch target and run that in debug.
Keep an eye on your watch homescreen as the app installs. Once the app has installed, tap it to open it. This will sometimes "kickstart" the watch app and allow the debugger to catch it. At this point you should be able to debug both your iPhone app and watchOS app together.
This question has different answers. All are good.
The reason is: in my experience there are at least two different problems that prevent debugging on a real watch. Both require a different strategy.
This answer tries to help you to decide when to use which strategy.
XCode installs, tells you it is running for a short time and then stops showing "running...".
start with the answer of BalestraPatrick:
restart your devices.
Do not forget to restart your iPhone. This did the trick the first time I had this problem.
XCode installs, tells you it is running for a longer period of time: "running <projectName> on Apple Watch of <yourname>.
start with the answer of Jay Hickey or Andrei Herford
starting the watch app manually probably does the trick.
I also had times when XCode was able to start my watch app without any help from me.
Bonus:
Starting with XCode 7.1 it seems XCode doesn't always compile all necessary Swift files (more often than before). This is not watch specific, it also applies to iOS apps. The symptoms can look similar to those of this question. -> clean your project and then restart XCode.
I'm trying to run a basic hello world watch app with an image. It is running fine in simulator but when I choose the iOS Device + Watch Device, app is taking time to load forever and not showing anything. I tried restarting phone/watch but nothing showed up.
Sounds like a familiar watchOS bug for me. :)
You should try to delete the watch app from your watch using the Watch app on your phone, then run it again. If it still loads infinitely, go to the watch's home screen and open it manually again.
When I try to build and run a WatchKit extension on my real Apple Watch, I sometimes get the following error message:
I've tried to build the parent application for the iPhone and then again for my WatchKit app but I still get the error message.
Does anyone know what causes this error message and how to deal with it?
This seems to happen when it takes a long time to install the WatchKit App on the actual watch and Xcode times out waiting for the process to start due to the long install time. It can take a long time for two reasons:
It sometimes takes a while for the Watch to "notice" the App needs updating before it begins the transfer.
If your Apple Watch app has a lot of images or other content it needs to transfer to the watch, the actual transfer over Bluetooth can take a long time.
If you want to avoid this error, here are some tips, adapting from this blog post, which can also show you how to speed up your app installs: http://www.sneakycrab.com/blog/2015/5/28/speeding-up-slow-install-times-when-debugging-on-a-real-apple-watch
Choose the iOS base scheme in Xcode to build and install on your phone. (Not the WatchKit App Extension)
Hit stop in Xcode.
Get iOS to notice it needs to begin installing the Watch app. There are two ways, either a) open the page for your app in the Apple Watch Companion App on your phone, or b) tapping on your app directly on the Watch (when you see the spinner, you can hit the crown to go back to the app icon screen, and you should see it start to load)
Once the app is installed on your watch, switch to the WatchKit Extension scheme and hit play, it will be waiting to attach debugging
Launch your app manually.
Make sure your iPhone bluetooth is turned on
Then I removed the app from my iPhone and re-launched it. That fixed it for me.
I'm writing a WatchKit app which needs to make a query to our Parse server. Because this is a network call, I follow the following procedure:
I make a call from WatchKit to the iOS app using openParentApplication:reply:
Inside of handleWatchKitExtensionRequest:userInfo:reply:, I start a background task with a UIBackgroundTaskIdentifier to ensure the iOS app isn't terminated immediately
I set up my PFQuery and call findObjectsInBackgroundWithBlock:
In the block I pass to the PFQuery, I reply the relevant information to the watch
I wrote this app maybe a month ago before the Apple Watch was out, and it ran just fine in the Watch simulator. Yesterday I received my Apple Watch and I was able to get the app running on the watch, but it doesn't quite work - I managed to figure out that when the iOS app is actively running in the foreground on the iPhone, then everything is great; but if the app is not active (e.g. backgrounded or terminated), then findObjectsInBackgroundWithBlock: never actually calls the block, and execution seems to just stop.
Does anyone have any ideas of what might be going on? My initial thought was that the iOS app is getting suspended/killed before it can complete the query, but I was pretty sure the background task would prevent that.
PS. If anyone stumbles upon this question because they were looking for how to get a WatchKit app running on an actual watch, I found this post extremely helpful in getting it working.
Turned out that I had several problems related to openParentApplication:reply:, and they all seem to have been resolved by using the technique from this post:
http://www.fiveminutewatchkit.com/blog/2015/3/11/one-weird-trick-to-fix-openparentapplicationreply
I had started a background task for my own app, but I didn't use the "bogus workaround" background task described in this post, because it wasn't necessary for me in the simulator. On the watch, though, it apparently was.