Watch Connectivity

RSS for tag

Implement two-way communication between an iOS app and its paired watchOS app using Watch Connectivity.

Watch Connectivity Documentation

Posts under Watch Connectivity tag

53 Posts
Sort by:
Post not yet marked as solved
0 Replies
417 Views
I am trying to run the watch and iphone simulator at the same time. I have removed all simulators using Xcode Devices & Simulators panel and created a single iPhone with a paired Apple Watch to eliminate as many variables as possible. I have two schemes, my iPhone app scheme and a Watch scheme. The Watch is NOT set to run independently. My problem is that I can not start the iPhone simulator and the watch simulator and debug both at the same time. As soon as I start one or the other the currently running process is killed, making it impossible to debug both at the same time. I feel like I had this working at one point so I'm not sure if this is a regression or not. Using Xcode 15.1.
Posted
by
Post not yet marked as solved
1 Replies
574 Views
Hey there, I'm implementing Watch Complications in an existing project, and I'm having the problem that transferCurrentComplicationUserInfo(_:) works exactly as transferUserInfo(_:) is described in the documentation, but not as it should. That is, when the WatchApp is opened, func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any] = [:]) receives the data sent by transferCurrentComplicationUserInfo(_:). If not, the data is queued until the Watch App is opened again. In other words, transferCurrentComplicationUserInfo(_:) never wakes up the ExtensionDelegate when the Watch App is not running. Has anyone experienced the same thing and know how to fix it? More details: Testing on iPhone 11 (iOS 17.1.2) and Apple Watch SE (WatchOS 10.2) I made sure that the quota of 50 is not exhausted when I test. The WatchApp is still dual-target (I want to avoid having to migrate to single-target and SwiftUI lifecycle) Watch App code: class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate { let session = WCSession.default override init() { super.init() if WCSession.isSupported() { session.delegate = self session.activate() } } func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any] = [:]) { WatchWidgetSessionHandler.shared.processComplicationUserInfo(userInfo) } } IOS App code: class WatchAppDataManager: NSObject, WCSessionDelegate { override init() { super.init() let session = WCSession.default session.delegate = self session.activate() } func sendDataToWidget(for kinds: [WatchWidgetKind]) async { guard WCSession.default.activationState == .activated, WCSession.default.isComplicationEnabled else { return } let widgetsData = dataProvider.getData(for: kinds) if !widgetsData.isEmpty { WCSession.default.transferCurrentComplicationUserInfo(widgetsData) } } }
Posted
by
Post not yet marked as solved
0 Replies
378 Views
https://developer.android.com/build/configure-app-module#set_the_application_id In Android, you can separate a mobile app and a wearable app into different projects and still enable communication by setting the same applicationId in both project's build.gradle.kts files. Thus, one may upload mobile app and wearable app into google store separately, and yet be able to receive/send messages with each other. Is there a similar approach available for iOS and watchOS apps? I tried separating the watchOS app into a new project and setting its WKCompanionAppBundleIdentifier to the original iOS app's Bundle Identifier. But I'm still encountering errors as below: WCSession counterpart app not installed SessionIsNotReachable Am I missing something, or is this approach not feasible on iOS/watchOS? Also, if it is not feasible, I would like to know why such approach is available on Android, but not on iOS. If it is feasible, correction for my approach, or introduction of a new approach would be greatly appreciated.
Posted
by
Post not yet marked as solved
1 Replies
577 Views
I am trying to add a watch target in my existing project using XCode 15.1 but I am not able to see any watch simulators for this to run my watch app. I created a small sample project separately where I can see watch simulators reflecting in the run destination. Can somebody please help me to locate which property or setting I need to check which is disabling XCode to show watch simulators? I have downloaded the watch simulator.
Posted
by
Post not yet marked as solved
0 Replies
618 Views
When connecting my iphone (14pro with iOS 17.2.1) with a paired apple watch (series 9 with OS 10.3), it is not showing up on the devices/simulators list in xcode 15.1. Beyond unpairing/repairing the watch, restarting either iphone or watch, connecting/disconnecting the iphone from the computer or deleting xcode and re-installing xcode, any other suggestions? Under the WatchApp field it shows "no eligible device connected", however, under the console the Apple Watch does appear. I have tried just about everything and can't get the watch to appear in Xcode. I am running all this on a MacBook Pro with Sonoma. Thanks for any assistance!
Posted
by
Post marked as Apple Recommended
2.6k Views
The iPhone Target Build Phase for my Apple Watch companion app specifies the source of the Product to embed as: build/Debug-watchos, however, the Watch build is located at build/Debug-watchsimulator. I am receiving an error from Xcode when trying to install the Apple Watch app in the watch simulator, as follows: An application bundle was not found at the provided path. Provide a valid path to the desired application bundle. Failed to install the requested application Domain: NSPOSIXErrorDomain Code: 2 Failure Reason: An application bundle was not found at the provided path. Recovery Suggestion: Provide a valid path to the desired application bundle. I have tried deleting the Watch target and re-adding the target but the misconfiguration remains. I have also tried adding my own Copy Build Phase but when selecting the Product for the Apple Watch companion app the same incorrect folder is used. Any ideas?
Posted
by
Post not yet marked as solved
1 Replies
499 Views
We are working on a WatchKit app that streams heart rate data to a companion iOS app. This works very well with WCSession, however, when the WatchKit app sleeps, the data does not continue to stream. The only way to get the data to stream again is by moving/touching the Apple Watch and waking it up again. We tried implementing a WKExtendedRuntimeSession, but we were unable to send data with this session. Is there a way to have data to continue to stream continuously, even if the watchkit app falls asleep? WatchOS: 8.8.1 iOS: 17.0 XCode: 15.0.1
Posted
by
Post not yet marked as solved
0 Replies
528 Views
TLDR: How can I listen to changes in SwiftData and share the data via WatchConnectivity? I am developing an app for the Apple Watch where the iPhone can act as a remote for the Watch. The App on the Watch should work independently from iPhone. The user can create elements on the Watch and start the action associated with the element. The iPhone user can see the elements created on the Watch and start the action on the Watch from the iPhone (if possible I want to add the functionality to let the user update the elements on both devices, but that's not a priority atm). I tried to get it to work with CloudKit and SwiftData, but somehow I couldn't get CloudKit to initialize correctly. After further research, I reconned that using WatchConnectivity and ApplicationContext should be a suitable approach. To communicate with the iPhone App, I created a singleton class that manages the communication. Now I want this class to listen to the changes in SwiftData to send the elements to the iPhone, but I don't know how I can get access to the ModelContext in the Communicator class. I read that passing the value from the initializer of a view is not good practice and it didn't work for me. What would be a suitable way to achieve the desired behavior of my app? Any help and feedback is appreciated. TIA
Posted
by
Post not yet marked as solved
0 Replies
363 Views
I'm currently developing an app for watchOS and I need to programmatically check the status of the paired Apple Watch within my app. Specifically, I want to determine if an Apple Watch is currently paired with the user's iPhone, or which watch is actively paired with user's iPhone if they switch to different watch. What is the recommended approach or API in watchOS to achieve this? Going through both DeviceInformation queries and DDM status channel, but I don't see anything helpful.
Posted
by
Post not yet marked as solved
2 Replies
608 Views
I have a WatchOS app that uses Push Navigation. I statrted to make a change this morning (Xcode 15.0, watchOS10), and discovered that the look of Push Navigation has changed dramatically. Instead of a back arrow "<" and title in the upper left corner, there is now a larger "<" in a dim circle, and the title is right-justified under the clock, with some background transparency. See attached image for a "old vs. new" comparison. In several cases, this isn't a problem, but I have some scenes in my app that require just about every bit of real estate of the screen, and now the UI loses a significant amount of room at the top. Does anyone know if there's a way to force the old behavior? If not, I may need to do some significant jiggering of my user interface!
Posted
by
Post not yet marked as solved
2 Replies
686 Views
I have an existing iOS/watchOS app that uses a third-party database and WatchConnectivity. For various reasons I am migrating the app to use Core Data with CloudKit. I have everything working using NSPersistentCloudKitContainer. Sync between the iOS and watchOS app are working on my test devices when I start with an empty database. However, I need to import existing user's data when they first install this new version. Some users may have hundreds or thousands of records, but the total database size is under 1-2MB. Data migration/import is working on the iOS side, the Core Data entities are populated on first launch and uploaded to CloudKit (I see in the debug logs that a NSPersistentCloudKitContainer.Event export ends successfully). The problem is launching the watchOS app does not sync the data from CloudKit. I see a import started event but never see it end. I never see any Core Data entities appear on watchOS even after waiting several minutes and re-opening the Watch app multiple times. New entities or modifications made on either app are also not synced. Is the problem just too much data which causes the CloudKit sync to never finish? What are the best practice to populate a watchOS app with initial data from the parent iOS app and keep it in sync with CoreData/CloudKit?
Posted
by
Post not yet marked as solved
1 Replies
486 Views
Hello All, I hope my first post here finds everybody doing well. I wish to develop a simple app. I have some coding experience using other technologies. This would be my first iOS and MacOS app. I am asking for advice regarding the choice of tools and or technology. Here is what I think potential advice givers need to know: Motivation is to keep evil coworkers from messing with my Mac when I step away from, (often), my desk In order to thwart their machinations, I have set my Mac to lock after a very short period of inactivity - this is often a pain as I am sitting at my desk when the Mac locks I wear a fairly new iWatch and am using an M2 Macbook Air I want an app that keeps my Mac from locking when I am nearby I want an agent that runs on my Mac that listens for pings from my iWatch I want an app for my iWatch that pings my Mac It would be nice to be able to set the radius of the "nearby zone" and ping rate A ping would interact with my agent so as to keep my Mac from locking If no ping, Mac locks per whatever time-out setting I have on my Mac I know, I know. I could just use some key combos. No need to point out the obvious way of dealing with the bozos, (we have fun), that I work with. Stymying them in this manner would enhance my happiness. I just want a bit of advice on the appropriate way of going about this. Hopefully, anything I learn might someday be applied to the development of other simple apps. Thanks for any thoughts offered! John Ullom
Posted
by
Post not yet marked as solved
0 Replies
482 Views
I work on an Apple Watch app that can preview what the iPhone camera sees, as well as controls it. I had one report of video quality seen on watchOS, both in resolution and FPS. The only time I've been able to reproduce this is with the "poor network quality" preset in the network link conditioner. Does this mean that the quality of the user's Wi-Fi connection is affecting their WatchConnectivity transfers?
Posted
by
Post not yet marked as solved
0 Replies
811 Views
I'm having a weird issue. I have a watch app which communicates with the phone using a WCSessionDelegate. if the phone app is open everything works fine, but if the app is closed, when the watch sends a message, my app is woken from the background, after which onAppear() is called in my app which causes a swiftData query to run. Calling any swiftdata function from a backgrounded app causes it to immediately crash with the following stack trace. Any ideas what im doing wrong? or a better way to trigger my code instead of onAppear, so it won't be called when my watch wakes my app from the background? .onAppear { reloadData() } private func reloadData() { let fetch = FetchDescriptor<SavedServer>( predicate: nil, sortBy: [.init(\.displayOrder)] ) guard let results = try? modelContext.fetch(fetch) else { self.rows = [] return } self.rows = results } ------------------------------------- Translated Report (Full Report Below) ------------------------------------- Incident Identifier: 057999AF-7840-410E-B3EE-29082C5AED00 CrashReporter Key: 28AF2AA0-4626-9964-9664-36077DAF4E1A Hardware Model: MacBookPro18,2 Process: MC Status [68915] Path: /Users/USER/Library/Developer/CoreSimulator/Devices/C61698BA-C4CA-4DD9-B824-DBF57AC65090/data/Containers/Bundle/Application/A685371C-9174-4CF7-9E99-D573310CC3E5/MC Status.app/MC Status Identifier: com.shemeshapps.MinecraftServerStatus Version: 2.0 (1) Code Type: ARM-64 (Native) Role: Non UI Parent Process: launchd_sim [55432] Coalition: com.apple.CoreSimulator.SimDevice.C61698BA-C4CA-4DD9-B824-DBF57AC65090 [164301] Responsible Process: SimulatorTrampoline [53834] OS Version: macOS 13.4.1 (22F82) Release Type: User Report Version: 104 Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Triggered by Thread: 0 Last Exception Backtrace: 0 CoreFoundation 0x18046589c __exceptionPreprocess + 160 1 libobjc.A.dylib 0x18005c09c objc_exception_throw + 56 2 CoreData 0x184989b94 -[NSFetchRequest(_NSInternalMethods) _incrementInUseCounter] + 0 3 CoreData 0x1849aa99c -[NSManagedObjectContext executeRequest:error:] + 164 4 CoreData 0x1848fe250 NSManagedObjectContext.fetch<A>(_:) + 80 5 SwiftData 0x1a89b7ad8 ModelContext.fetch<A>(_:) + 124 6 SwiftData 0x1a89c48c0 dispatch thunk of ModelContext.fetch<A>(_:) + 20 7 MC Status 0x102530ef4 MainAppContentView.reloadData(forceRefresh:) + 752 (MainAppContentView.swift:112) 8 MC Status 0x102533540 closure #2 in MainAppContentView.body.getter + 44 (MainAppContentView.swift:78) 9 SwiftUI 0x108a0b7a0 0x107b8c000 + 15202208 10 SwiftUI 0x108a0b7bc 0x107b8c000 + 15202236 11 SwiftUI 0x108a0b7a0 0x107b8c000 + 15202208 12 SwiftUI 0x108fdce70 0x107b8c000 + 21302896 13 SwiftUI 0x108fd6ec0 0x107b8c000 + 21278400 14 SwiftUI 0x1081edb24 0x107b8c000 + 6691620 15 SwiftUI 0x10928d650 0x107b8c000 + 24122960 16 libdispatch.dylib 0x1801424f4 _dispatch_call_block_and_release + 24 17 libdispatch.dylib 0x180143d3c _dispatch_client_callout + 16 18 libdispatch.dylib 0x180152b24 _dispatch_main_queue_drain + 1272 19 libdispatch.dylib 0x18015261c _dispatch_main_queue_callback_4CF + 40 20 CoreFoundation 0x1803c61b4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 21 CoreFoundation 0x1803c08cc __CFRunLoopRun + 1936 22 CoreFoundation 0x1803bfd28 CFRunLoopRunSpecific + 572 23 GraphicsServices 0x189864bc0 GSEventRunModal + 160 24 UIKitCore 0x103b30208 -[UIApplication _run] + 868 25 UIKitCore 0x103b33e80 UIApplicationMain + 124 26 SwiftUI 0x108a10524 0x107b8c000 + 15222052 27 SwiftUI 0x108a103c4 0x107b8c000 + 15221700 28 SwiftUI 0x108722088 0x107b8c000 + 12148872 29 MC Status 0x102506d30 static MCStatusApp.$main() + 40 30 MC Status 0x102506de0 main + 12 (MCStatusApp.swift:12) 31 dyld_sim 0x1028fd558 start_sim + 20 32 dyld 0x1026b1f28 start + 2236 33 ??? 0x3c15800000000000 ??? Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x102f1cfa8 __pthread_kill + 8 1 libsystem_pthread.dylib 0x10285712c pthread_kill + 256 2 libsystem_c.dylib 0x1801375ec abort + 104 3 libc++abi.dylib 0x180263c78 abort_message + 128 4 libc++abi.dylib 0x180255198 demangling_terminate_handler() + 300 5 libobjc.A.dylib 0x180037bf0 _objc_terminate() + 124 6 libc++abi.dylib 0x180263150 std::__terminate(void (*)()) + 12 7 libc++abi.dylib 0x180263100 std::terminate() + 52 8 libdispatch.dylib 0x180143d50 _dispatch_client_callout + 36 9 libdispatch.dylib 0x180152b24 _dispatch_main_queue_drain + 1272 10 libdispatch.dylib 0x18015261c _dispatch_main_queue_callback_4CF + 40 11 CoreFoundation 0x1803c61b4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 12 CoreFoundation 0x1803c08cc __CFRunLoopRun + 1936 13 CoreFoundation 0x1803bfd28 CFRunLoopRunSpecific + 572 14 GraphicsServices 0x189864bc0 GSEventRunModal + 160 15 UIKitCore 0x103b30208 -[UIApplication _run] + 868 16 UIKitCore 0x103b33e80 UIApplicationMain + 124 17 SwiftUI 0x108a10524 0x107b8c000 + 15222052 18 SwiftUI 0x108a103c4 0x107b8c000 + 15221700 19 SwiftUI 0x108722088 0x107b8c000 + 12148872 20 MC Status 0x102506d30 static MCStatusApp.$main() + 40 21 MC Status 0x102506de0 main + 12 (MCStatusApp.swift:12) 22 dyld_sim 0x1028fd558 start_sim + 20 23 dyld 0x1026b1f28 start + 2236
Posted
by
Post marked as solved
3 Replies
1.2k Views
When calling WCSession.default.transferCurrentComplicationUserInfo , the watch extension does not wake (init is never called) when the watch application is inactive. It does work fine when the watch application is in the foreground. And the didReceiveUserInfo is being called. WidgetKit developer mode is set, so that remainingComplicationUserInfoTransfers is not an issue. using watchOS 9.5 and SwiftUI / WidgetKit complications.
Posted
by
Post not yet marked as solved
10 Replies
3.1k Views
We are migrating ClockKit complications to WidgetKit in our watch app (watchOS 9+). The migration went smoothly, UI part works just fine. However, we've hit the wall with widgets not updating when requested by the watch app. I believe we are missing something very simple and fundamental, but couldn't find what exactly so far. Advice and tips would be very welcome! 🙇‍♂️ Our implementation details: Whenever data is changed in the main app, the updated data is submitted to the watch app via WatchConnectivity framework using WCSession.default.transferCurrentComplicationUserInfo(_:). According to documentation, this method should be used to transfer complication-related data, since it will wake the watch app even if it is in the background or not opened at all. Watch app receives updated data and stores it in UserDefaults shared with Watch Widget Extension hosting WidgetKit complications via App Group. Watch app then request widget timeline reload via WidgetCenter.shared.reloadAllTimelines(). According to documentation, it reloads the timelines for all configured widgets belonging to the containing app, so it seems the appropriate way to reload WidgetKit complications. Widget Timeline Provider class in Watch Widget Extension reads updated data from shared UserDefaults and uses it to provide the updated snapshot for widget views to render. We believe our implementation logic is correct, but it doesn't work, for some reason. Widgets sometimes update when the watch app is opened, but not always. The most definitive way to force widgets to update is to switch to a different watch face, which confirms that the Widget Timeline Provider has access to properly updated data. P.S. We are aware of the daily reload budget imposed on widgets, so we use widgets reload trigger sparingly. Anyway, according to documentation, reload budget is not effective when in DEBUG mode, but widgets won't reload even in DEBUG mode. Thank you!
Posted
by
Post not yet marked as solved
1 Replies
435 Views
I'm using Watch Connectivity to transfer files from the Watch to its paired iOS device. File transfer is successful in my first tests, but obviously I need to erase the source file when it is - successfully - sent. When should I do that? just after initiating the file transfer, using transferFile(file: NSURL, metadata: [String : AnyObject]) when getting the returned WCSessionFileTransfer? when getting the callback func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer ? --> but will the callback always be called, even if the transfer finishes while the app is in background? some other time? NB: I'd really want to avoid implementing a custom 'ack' system, thus not using any user info/application context transfer.
Posted
by