WatchKit

RSS for tag

Build apps that leverage watchOS features like background tasks, extended runtime sessions, and access to the Digital Crown using WatchKit.

WatchKit Documentation

Posts under WatchKit tag

138 Posts
Sort by:
Post not yet marked as solved
0 Replies
65 Views
I noticied that my workout session is sometimes being killed by apple when the app is in the background and it seems that the func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) { is only being called when the app comes back into the foreground. I wonder if there is a way for us to get notified when the workout is about to die or has already been killed. Thanks
Posted
by
Post not yet marked as solved
1 Replies
70 Views
Hello Apple Developer Forum, I'm reaching out because I've encountered an issue with my app's implementation involving the ScrollView and the digitalCrown, and I'm hoping to find some guidance or assistance from the community. Currently, I'm developing an app where users can navigate through dates using the digitalCrown to change the "$scrollAmount", which then dynamically updates the ScrollView with events corresponding to that date. However, I've run into a problem where the ScrollView is being inadvertently scrolled by the digitalCrown every time it's initiated. Ideally, I would like to disable the digitalCrown's interaction with the ScrollView altogether, so that the ScrollView is only scrolled using touch inputs and not by the digitalCrown. I've tried several approaches to achieve this, but haven't had much success so far. Could anyone please provide some guidance or suggestions on how I can effectively disable the digitalCrown's interaction with the ScrollView while still allowing touch-based scrolling? Any help or insights into this matter would be greatly appreciated. Thank you very much in advance for your time and assistance. Best regards, Example code: var body: some View { NavigationView { VStack { HStack{ Text("\(formattedDate(for: scrollAmount, format: lineOne))") .onTapGesture { scrollAmount = 0.0 } } ScrollView{ ForEach(viewModel.events, id: \.event) { viewModelItem in let event = viewModelItem.event VStack { HStack { Text(event.title) } } } } .scrollDisabled(true) } } .focusable(isFocused) .digitalCrownRotation( detent: $scrollAmount, from: -365.0, through: 365.0, by: 1.0, sensitivity: .low, isContinuous: false, isHapticFeedbackEnabled: true) .onChange(of: scrollAmount) { let roundedValue = round(scrollAmount) scrollAmount = roundedValue viewModel.fetchEvents(for: scrollAmount) } } }
Posted
by
Post not yet marked as solved
0 Replies
70 Views
Hi, I'm triggering a notification from the audio interruption handler (but also have a debug button set to trigger it manually) and it frequently does not show up. I don't think I have ever seen it show up when the watch face is off. I have created a singleton class to trigger this notification as follows. Note that I use a UUID in the identifier because an old thread here suggests this is necessary, but it makes no difference as far as I can tell. Any ideas? I'd like this notification to be reliable. I'm also surprised that with trigger set to nil, it does not trigger instantaneously. Any help would be much appreciated! Thanks, -- B. import Foundation import UserNotifications class NotificationSender: NSObject, UNUserNotificationCenterDelegate { static let shared = NotificationSender() override init() { super.init() let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.sound, .badge]) { granted, error in if granted { print("Notification permission granted") } else { print("Notification permission denied") } } center.delegate = self // Define the action to open the app let openAction = UNNotificationAction(identifier: "openAction", title: "Open App", options: [.foreground]) // Add the action to the notification content let category = UNNotificationCategory(identifier: "resumeAudioCategory", actions: [openAction], intentIdentifiers: [], options: []) center.setNotificationCategories([category]) } func sendNotification() { let center = UNUserNotificationCenter.current() let content = UNMutableNotificationContent() content.title = "Recording Interrupted" content.body = "You will need to restart it manually." content.categoryIdentifier = "resumeAudioCategory" // Create the notification request //let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) let request = UNNotificationRequest(identifier: "ResumeAudioNotification-\(UUID().uuidString)", content: content, trigger: nil) center.add(request) { error in if let error = error { print("Error adding notification request: \(error)") } } } // Handle notification when the app is in the foreground func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // Display the notification while the app is in the foreground completionHandler([.sound, .badge, .banner, .list]) } // Handle notification response func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // Handle the user's response to the notification // For example, navigate to a specific screen in your app completionHandler() } }
Posted
by
Post not yet marked as solved
0 Replies
102 Views
I am developing an AppleWatch applet. There is no IOS side, only the Apple Watch side. I want to evoke SIRI on the Apple Watch, then say "Open my software" or a specific sentence, and then my software will be automatically opened.
Posted
by
Post not yet marked as solved
2 Replies
222 Views
Good morning, I come to you for a question: When I install my application on my iPhone for the first time, and I install the watch application from the native "Watch" application, the Watch Connectivity function does not work, I have to do the installation from Xcode to the watch for this function to work. Is this normal? if yes, the problem will not arise during a publication? I have the same problem when using watch and iPhone simulators, WatchConnectivity does not work. I am this error code in Xcode: -[WCSession handleIncomingUserInfoWithPairingID:]_block_invoke delegate (null) does not implement session:didReceiveUserInfo:, discarding incoming content Here is the code for the iPhone and the watch: In my iPhone app: import WatchConnectivity let userDefaultsDataVenantWatch = UserDefaults.standard class PhoneDataModel : NSObject, WCSessionDelegate, ObservableObject { static let shared = PhoneDataModel() let session = WCSession.default @Published var TableauSynchroIphoneVersWatch : [String:String] = ["0":"0"] @Published var dataWatchVersIphone: [String:String] = ["":""] override init() { super.init() if WCSession.isSupported() { session.delegate = self session.activate() } else { print("ERROR: Watch session not supported") } } func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { if let error = error { print("session activation failed with error: \(error.localizedDescription)") return } } func sessionDidBecomeInactive(_ session: WCSession) { session.activate() } func sessionDidDeactivate(_ session: WCSession) { session.activate() } func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any]) { guard let newCount = userInfo["TableauSynchroIphoneWatch"] as? [String:String] else { print("ERROR: unknown data received from Watch TableauSynchroIphoneWatch") return } DispatchQueue.main.async { print(newCount) } } } In my Watch app: import WatchConnectivity let userDefaultsDataVenantIphone = UserDefaults.standard var TableauVenantIphone:[String:String] = ["":""] class WatchDataModel : NSObject, WCSessionDelegate, ObservableObject { static let shared = WatchDataModel() let session = WCSession.default @Published var TableauSynchroIphoneWatch : [String:String] = ["0":"0"] override init() { super.init() if WCSession.isSupported() { session.delegate = self session.activate() } else { print("ERROR: Watch session not supported") } } func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { if let error = error { print("session activation failed with error: \(error.localizedDescription)") return } } func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any]) { guard let newCount = userInfo["TableauSynchroIphoneVersWatch"] as? [String:String] else { print("ERROR: unknown data received from Watch TableauSynchroIphoneWatch") return } DispatchQueue.main.async { print(newCount) } } } Thank for your answers !
Posted
by
Post not yet marked as solved
0 Replies
149 Views
AFAIK, background execution with Background Tasks framework is all budgeted. E.g., if we try to use it too much, the system would simply stop letting us do it, at least for some time. Is it the same when we do sendMessage from Watch app to iOS app? Is there a chance we may overuse it so that system stops waking up the iOS app? Or I can rely and use sendMessage as often and heavy as I need?
Posted
by
Post not yet marked as solved
3 Replies
177 Views
I did a timer that fires every thousandth of a second and it stops after a certain period of time unless I restart the watch and this doesn't happen in the watch simulator so something is wrong with the real watch while the simulator doesn't show this phenomenon. There is definitely a lower software stack bug or the processor cannot handle the load while the Ultra and Ultra 2 have no problems AFAIK.
Posted
by
Post not yet marked as solved
5 Replies
297 Views
It's not just me that the watch doesn't show up in Xcode 15.3, Watch 10.4, iOS 17.4.1, right? In Xcode, the Mac and iPhone are connected and displayed, but only the watch is not working. And when I run the complication app, oddly enough, it prompts to install the app on the iPhone device's watch app? It's really strange, isn't it? But the installation doesn't actually happen. It seems like a funny thing with Apple. Does anyone know when this will be fixed?
Posted
by
Post not yet marked as solved
1 Replies
198 Views
Wanted to reach out for some assistance with troublshooting my watch app not detecting collision, I have set up a few breakpoints and determined that it is not running the game over struct even if it had detected the collision, I have also tried to generate a log file when a collision is detected and that does not work either. I have considered that the objects may not be on the same layer so they are now in the same zstack.
Posted
by
Post not yet marked as solved
1 Replies
382 Views
Hi there, I think I may have caught a bug in the iOS system. Please confirm. Problem Newly installed Watch-Only and Independent apps on the Apple Watch do not have a network connection when paired with an iPhone until the iPhone is rebooted. Please see the attached screenshot; the iPhone indicates 'WiFi and Cellular policy: kDeny'. Use Case For our end-users, they will install the Watch-Only app directly from the App Store on the Apple Watch, and of course, their watch is paired with their iPhone. In this case, the Watch-Only app has no network connection at all after installation. The user has to reboot the iPhone once, and then the Watch-Only app can access the network. It is unacceptable for the end-users. System Info WatchOS: 10.1.1 Watch Model: A2770, Apple Watch Series 8 (GPS only) iOS Version: 17.4.1 iPhone Model: iPhone 15 XCode: 15.3 How to reproduce Please download the very simple sample code attached. It features the official URLSession Demo Code, which initiates a default URLSession to access https://www.example.com. ContentView.swift Prepare an iPhone and an Apple Watch, then connect the watch to the iPhone and ensure they are paired correctly. Ensure that your iPhone properly connects to a working WiFi network. Now, connect both your Apple Watch and iPhone to Xcode and run the code on the watch. Xcode will then install the Watch-Only app on your watch. After installation, click the 'Click' button on the watch app, and you will receive an error message stating 'The Internet connection appears to be offline...' Now, check the Console output of your iPhone and filter by 'wifi policy'. You will see logs stating 'Adding CU Policy: Bundle IDs: (the-bundle-id) Wifi policy: kDeny Cellular policy: kDeny'. Now, reboot your iPhone and wait for it to reconnect to the WiFi network. Check the Control Center on your watch to ensure the little green iPhone icon is displayed, indicating that your watch is now paired correctly with the iPhone. Click the 'Click' button again on the watch app, and this time it will work perfectly. To repeat the process, simply uninstall the watch app from your watch, and run the sample code again. Xcode will reinstall the app onto the watch. This time, the app will not work until you reboot the iPhone again. References Proxy Through iPhone https://developer.apple.com/documentation/watchos-apps/keeping-your-watchos-app-s-content-up-to-date#Test-your-update-code-with-different-configurations Sample Code struct ContentView: View { @State var txt = "Hello World!" var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text(txt) Button("Click") { startLoad() } }.padding() } func startLoad() { let config = URLSessionConfiguration.default config.waitsForConnectivity = false config.allowsCellularAccess = true config.allowsExpensiveNetworkAccess = true config.allowsConstrainedNetworkAccess = true let sesh = URLSession(configuration: config) let url = URL(string: "https://www.example.com")! sesh.dataTask(with: url) { data, response, error in if let error = error { self.txt = error.localizedDescription // self.handleClientError(error) return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { self.txt = response.debugDescription // self.handleServerError(response) return } if let mimeType = httpResponse.mimeType, mimeType == "text/html", let data = data, let string = String(data: data, encoding: .utf8) { DispatchQueue.main.async { self.txt = string // self.webView.loadHTMLString(string, baseURL: url) } } }.resume() } } #Preview { ContentView() }
Posted
by
Post not yet marked as solved
0 Replies
177 Views
Hello fellow developers, I've recently developed a workout companion watch app for iOS. However, I'm now have a task of implementing custom workouts for my app. I've come across a video demonstrating how to create and schedule custom workouts for the watch app, which I believe will be incredibly helpful for my project. Video Link: Creating Custom Workouts for iOS Watch App If anyone knows of any additional resources, such as articles or videos, that further explores this topic, I would greatly appreciate it if you could share them with me. Thank you for your assistance! Best regards, Pranit Bhogale
Posted
by
Post not yet marked as solved
0 Replies
228 Views
This page describes the procedure to create deep links in iOS. I was able to launch an IOS Companion app (name of the app in my case) using its deep link. But the same is not working in AppleWatch. This is my plist to register a custom scheme - Companion: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleURLTypes</key> <array> <dict> <!-- <key>CFBundleTypeRole</key> <string>Viewer</string> --> <key>CFBundleURLName</key> <string><some unique ID></string> <key>CFBundleURLSchemes</key> <array> <string>Companion</string> </array> </dict> </array> </dict> </plist> I have implemented onOpenURL(perform:) to handle app launches using a deep link (url). var body: some Scene { WindowGroup { ContentView() .onOpenURL(perform: { (link: URL) in Log(String(format: "Link = %@", link.absoluteString)) // Use then deep link }) } } In iOS, I tested deep links in two ways: Wrote the full deep link in Notes app and tapped it. Created another app called AppLauncher with a Button saying 'Launch using Deep link'.... which when clicked opens the deep link using open(_:options:completionHandler:). Both the approaches work in iOS, but in watchOS, I can only try 2 because Notes app is not available for AppleWatch. So, I created another watchOS app called AppLauncher, which displays a SwiftUI Button saying 'Launch using Deep link', which when tapped, tries to open the link using openSystemURL(_:). But as mentioned in the documentation (linked earlier), Opens the specified system URL. this API only works for links associated with System apps i.e., Apple's call and message apps. So, how else can I use deep link to launch another app? I believe it's possible to launch an app using its deep link because the info.plist keys required to define a deep link scheme association (CFBundleURLTypes, CFBundleURLSchemes etc) is valid for watchOS too.
Posted
by
Post not yet marked as solved
1 Replies
268 Views
I am trying to get iPhone and watch simulator to send message to each other. I am getting this error(s) all the time: Error Domain=WCErrorDomain Code=7012 "Message reply took too long." UserInfo={NSLocalizedDescription=Message reply took too long., NSLocalizedFailureReason=Reply timeout occurred.} -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] 0F2558A6-6E42-4EF1-9223-FBC5336EE490 errorHandler: YES with WCErrorCodeMessageReplyTimedOut Is there are some guideline on how to connect them together? Maybe I a missing some step. For clarification, sometimes they do connect but it feels like pure luck. Please help.
Posted
by
Post not yet marked as solved
0 Replies
283 Views
I'm making a watchOS app, which has WKNotificationScene for dynamic notification, and button for open sms app. I've tried to open sms app via url with following orders, but I always get error below: Press Notification on watchOS, which is made of WKNotificationScene (a.k.a. dynamic notification) watchOS App comes to foreground. Press button, which executes WKApplication.openSystemURL(_:) to open SMS App Error occurs. Failed to open URL sms:01022221111&body=%EB%82%98%EC%A4%91%EC%97%90%20%EC%A0%84%ED%99%94%EB%93%9C%EB%A6%AC%EA%B2%A0%EC%8A%B5%EB%8B%88%EB%8B%A4.: Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 "The request to open "com.apple.MobileSMS" failed." UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (IOSSHLMainWorkspace) for reason: Security ("Entitlement com.apple.springboard.openurlinbackground required to open URLs while backgrounded")., NSLocalizedDescription=The request to open "com.apple.MobileSMS" failed., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x176bf6b0 {Error Domain=FBSOpenApplicationErrorDomain Code=3 "Entitlement com.apple.springboard.openurlinbackground required to open URLs while backgrounded." UserInfo={BSErrorCodeDescription=Security, NSLocalizedFailureReason=Entitlement com.apple.springboard.openurlinbackground required to open URLs while backgrounded.}}, FBSOpenApplicationRequestID=0xaecb} -[SPApplicationDelegate extensionConnection:openSystemURL:]_block_invoke:2386: Attempting to open url sms:01011112222&body=%EB%82%98%EC%A4%91%EC%97%90%20%EC%A0%84%ED%99%94%EB%93%9C%EB%A6%AC%EA%B2%A0%EC%8A%B5%EB%8B%88%EB%8B%A4. with scheme sms failed: Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 "The request to open "com.apple.MobileSMS" failed." UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (IOSSHLMainWorkspace) for reason: Security ("Entitlement com.apple.springboard.openurlinbackground required to open URLs while backgrounded")., NSLocalizedDescription=The request to open "com.apple.MobileSMS" failed., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x176bf6b0 {Error Domain=FBSOpenApplicationErrorDomain Code=3 "Entitlement com.apple.springboard.openurlinbackground required to open URLs while backgrounded." UserInfo={BSErrorCodeDescription=Security, NSLocalizedFailureReason=Entitlement com.apple.springboard.openurlinbackground required to open URLs while backgrounded.}}, FBSOpenApplicationRequestID=0xaecb} I've tried to check WKApplicationState.active before executing WKApplication.openSystemURL(_:), but it always failed. Does anyone know how to fix it?
Posted
by
Post not yet marked as solved
1 Replies
280 Views
Hi, we have an old cordova/phonegap app that we are trying to upload through Transporter, but suddenly we started getting the following error: "Missing Info.plist value. A value for the key “WKApplication”, or “WKWatchKitApp” if your project has a WatchKit App Extension target, is required in “.app/.app” bundle. For details, see:" We don't support Apple Watch and there is no target for Apple Watch, there does not seem to be anything to do with Apple Watch in our XCode project, yet we are getting the above complain. We using the following versions: XCode 15.0 Cordova: 12.0.0 cordova-ios: 6.3.0 There has been no change to our provisioning profile. Any idea why we are getting the above complain?
Posted
by
Post not yet marked as solved
0 Replies
257 Views
Enable Developer Mode - Missing Trust this computer - Missing, if the prompt happens and you accidentally tap the verbiage or the crown before scrolling to the buttons, you never ever see the trust this computer again. Double tapping the side button or crown to kill apps is a game of roulette. If you don’t swipe the app in mere seconds the list disappears or one of the background apps becomes active. After upgrading all watches to 10.4 and pairing to a phone guess what? Enable developer mode - missing. Now I have a few watches that cannot be used for development. When is Apple going to address this glaring bug people have been reporting and talking about in the forums for almost a year with versions of watchos from as early as 9.x and iOS 16?
Posted
by