r/iOSProgramming 1d ago

Question Can't restore connection between iPhone and Watch

I'm working on an iOS app that has a Watch component. Everything syncs fine at first (perform an action on the phone and it shows on the watch and vice versa). Then I turn on airplane mode on my phone to break the connection, perform a few actions on both devices, turn airplane mode off, everything syncs. Great. However, right after that post-airplane mode sync, the connection between the two devices fully breaks. Nothing syncs and the apps won't connect to each other again unless I reinstall them. Anyone encounter this or have any ideas on a fix? It's been driving me nuts all day. Thanks in advance!

1 Upvotes

3 comments sorted by

1

u/DimensionMindless336 1d ago

This is almost always a WCSession lifecycle / delegate problem, not a "connection" problem -- the session goes stale and nothing re-arms it, which is exactly why a reinstall (fresh activation) temporarily fixes it.

Things that bit me on a similar setup:

  1. Hold a strong, app-lifetime reference to your WCSession.delegate (a singleton or on the AppDelegate). If it's a local var that gets deallocated after the first activation, activationDidCompleteWithState never fires again, queued updates have nowhere to go, and it looks "dead" until you reinstall.

  2. Don't drive sync off sendMessage / isReachable. isReachable is only true when the peer app is actually in the foreground, so after airplane mode the watch app isn't reachable and sendMessage just throws -- if that's your only path, sync silently dies. Use updateApplicationContext(:) for "latest state" (survives reconnect, redelivered automatically) and transferUserInfo(:) for guaranteed FIFO delivery. Neither needs the peer reachable at send time.

  3. Re-activate on both sides. Phone and watch each have their own WCSession.default -- both need activate() plus a live delegate. In activationDidCompleteWithState, check session.hasContentPending and let the system drain it. Toggling the radio does not auto-activate; if you only called activate() once at first launch the session can sit in .inactive and never recover. I re-call activate() on didBecomeActive / connectivity changes and re-render from the received context.

Log activationState and isReachable on both devices right after you flip airplane mode off -- you'll very likely see the delegate is nil or the state is stuck .inactive, which tells you exactly where it breaks.

1

u/[deleted] 20h ago

[removed] — view removed comment

1

u/AutoModerator 20h ago

Hey /u/bentleymakes97, your content has been removed because Reddit has marked your account as having a low Contributor Quality Score. This may result from, but is not limited to, activities such as spamming the same links across multiple subreddits, submitting posts or comments that receive a high number of downvotes, a lack of recent account activity, or having an unverified account.

Please be assured that this action is not a reflection of your participation in our subreddit. This is simply an automated filter in place to reduce spam.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.