How can I implement a feature in my iOS and watchOS app to prompt users to download it when they try to apply a custom watch face shared from my app, as shown in the example image? We're using WidgetKit for Complications.
Posts under watchOS tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
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()
}
Hello,
I have a TabView containing multiple views where one of them contains a list of items. The digital crown on the apple watch does not allow me to scroll the items in the tabview but only scrolls the list of items. Is there any way to disable that the scrolling of the list is done by the wheel or even a way to prioritize the digital crown to scroll the tabView and not the list?
Thanks
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.
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.
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?
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?
There is a app I’m trying to download on my watch (watchos only app) and it’s not downloading it’s just loading only and it keeps loading until the install button shows up again hours later
XCode 15.3, watchOS 10.4 SDK
Our health-related app is exploring adding an additional feature that would make use of extended runtime sessions to guide users through an activity. A user starts a session by tapping a button on the watchOS app's interface. If a session is already running, pressing that button should cause the current session to invalidate, and a new session should be created so we can start again from the beginning.
TLDR: Running new sessions works as expected on the simulator but not on a real device. Why?
We currently have a barebones implementation that includes logging in the extended runtime session delegate functions, on the button push, and when the new session is about to start.
Here's what our logging output for the simulator looks like when we try to invalidate the current session and run another one:
Invalidating extended session Optional("<WKExtendedRuntimeSession: 0x60000262d7a0> state=2, sessionID=4894EB1D-96F7-4921-8263-378E304E719F, expirationDate=2024-03-20 13:01:10 +0000") at 12:01:21 PM
Extended runtime session <WKExtendedRuntimeSession: 0x60000262d7a0> state=3, sessionID=4894EB1D-96F7-4921-8263-378E304E719F, expirationDate=2024-03-20 13:01:10 +0000 invalidated for reason WKExtendedRuntimeSessionInvalidationReason(rawValue: 0) with error nil at 12:01:21 PM
Requesting new extended session in application state 0 at 12:01:22 PM
Starting new extended session Optional("<WKExtendedRuntimeSession: 0x600002644540> state=0, sessionID=B34ECCFF-A0DA-45C1-9FD1-FD0F335FBE02, expirationDate=(null)") in application state 0 at 12:01:23 PM
Did start extended session <WKExtendedRuntimeSession: 0x600002644540> state=2, sessionID=B34ECCFF-A0DA-45C1-9FD1-FD0F335FBE02, expirationDate=2024-03-20 13:01:23 +0000 at 12:01:23 PM
As you can see, we successfully invalidate a running session, a button press requests a new one, and then we create and start a new runtime session instance which ends in the running (2) state. We can repeat this over and over without issue. The exact same code running on an actual device produces this:
Invalidating extended session Optional(\"<WKExtendedRuntimeSession: 0x15db5750> state=2, sessionID=889FE2E8-0FDA-4826-9094-4D48094FEBED, expirationDate=2024-03-20 12:53:55 +0000\") at 11:56:04AM
Extended runtime session <WKExtendedRuntimeSession: 0x15db5750> state=3, sessionID=889FE2E8-0FDA-4826-9094-4D48094FEBED, expirationDate=2024-03-20 12:53:55 +0000 invalidated for reason WKExtendedRuntimeSessionInvalidationReason(rawValue: 0) with error nil at 11:56:04AM
Requesting new extended session in application state 0 at 11:56:05AM
Starting new extended session Optional(\"<WKExtendedRuntimeSession: 0x15e0aba0> state=0, sessionID=D5020337-D20B-48BE-B2EE-EE44BE580AEC, expirationDate=(null)\") in application state 0 at 11:56:06AM
Extended runtime session <WKExtendedRuntimeSession: 0x15e0aba0> state=3, sessionID=D5020337-D20B-48BE-B2EE-EE44BE580AEC, expirationDate=(null) invalidated for reason WKExtendedRuntimeSessionInvalidationReason(rawValue: 1) with error nil at 11:56:06AM
The difference is in the last line: starting the session was unsuccessful and it was immediately invalidated, with the reason WKExtendedRuntimeSessionInvalidationReason(rawValue: 1) which maps to the enum sessionInProgress. This is surprising, since we just invalidated and dereferenced the old runtime session. What else can we do to tear down this session?
In fact, no other extended runtime sessions can be created and started successfully until the device is rebooted.
One note is that on the simulator we do get the following warning right after invalidating the running session:
-[WKExtendedRuntimeSession _invalidateWithError:]_block_invoke_2:527: Got error Error Domain=com.apple.CarouselServices.SessionErrorDomain Code=3 "Session not running <CSLSession: 0x600003b4eca0; pid: 8833; dismissed: NO; ended: YES; duration: 3600.0; autoEnd: NO; launchable: NO; mutuallyExclusive: YES; managed: YES; persisted: NO; requiresFGActiveInitiation: YES; lastForeground: 2024-03-20 12:01:21 +0000> |CSLSSession = {
| sessionID: 4894EB1D-96F7-4921-8263-378E304E719F; bundleID: com.bundle; type: "physical therapy"; running: NO; paused: NO; expirationDate: 2024-03-20 13:01:10 +0000; supportsAOT: NO; lastStartWasScheduled: NO; remote: NO;
|}" UserInfo={NSLocalizedDescription=Session not running <CSLSession: 0x600003b4eca0; pid: 8833; dismissed: NO; ended: YES; duration: 3600.0; autoEnd: NO; launchable: NO; mutuallyExclusive: YES; managed: YES; persisted: NO; requiresFGActiveInitiation: YES; lastForeground: 2024-03-20 12:01:21 +0000> |CSLSSession = {
| sessionID: 4894EB1D-96F7-4921-8263-378E304E719F; bundleID: com.bundle; type: "physical therapy"; running: NO; paused: NO; expirationDate: 2024-03-20 13:01:10 +0000; supportsAOT: NO; lastStartWasScheduled: NO; remote: NO;
|}}
This appears to be thrown by some part of Carousel, for which no public documentation exists, and it clearly doesn't disrupt the expected behavior on the simulator. I don't know if this is being thrown on the device, since our logging wouldn't be able to pick it up.
Please let me know if we are approaching this incorrectly or if there are any known solutions to this issue.
As per iOS SMS sending API, there is no option to send SMS programmatically without user consent. Developer needs to use the MessageUI framework to get iPhone user consent for sending SMS.
In that case, if any third party SmartWatch connected through BLE with iPhone received SMS notification through ANCS and want to reply to that SMS, After typing and sending from Watch, user needs to perform this additional step in iPhone - give consent.
But if we use Apple watch, this consent in iPhone is not required if Apple Watch is already paired with iPhone. After typing text in Apple Watch, can send SMS to receiver through utilizing iPhone's SMS service without any user interaction.
What is the reason of this difference?
For sending SMS, iPhone and Apple Watch needs to be paired. Similarly, even third party SmartWatch also performs BLE connection and pair together before sending SMS text from Watch to iPhone to forward to receiver.
But in that case why another additional user consent is required in iPhone? If we consider iPhone and Apple Watch case, pairing with each other is considered as user consent for sending any SMS later from Watch utilizing iPhone.
Then, why BLE pairing between iPhone and other third party Watch not considered as user consent and additional user consent is required for each time SMS sending?
My requirement is to execute this shortcut on the Apple Watch, where I input speech, and it's converted into text to be saved in the memo app. However, the shortcut doesn't function correctly on the Apple Watch, and I can't sync the content to the memo app. Suspecting an issue with synchronization, I added the current time along with my voice input, only to find that while the current time gets transferred, the text does not.
I wondered if the problem was with voice input, so I tried switching to keyboard input, but the outcome remained unchanged.
I have tested this issue on multiple Apple Watches and found the problem persists across all devices. Both my phone and iWatch are updated to the latest system versions.
https://www.icloud.com/shortcuts/d58d14627dbe450ead5e9217e1a68c27
Upgrade phone, then watch was paired to the new phone with developer mode enabled, but developer mode on watch is no longer visible on watchOS 10.4
Our app is pushed to supervised iPhones through our MDM. We have a watchOS companion app that we install to paired Apple Watches as well. Our watches are NOT enrolled in the MDM using the new watchOS 10 MDM features, and are just paired normally to the supervised phones.
Historically (the past 2 years), the watchOS companion app has been installed automatically after our iOS app has been pushed by our MDM (through VPP) and the Watch has been paired.
NEW IN iOS 17.4/watchOS 10.4, the watchOS companion app is NOT installed automatically and when we press “Install” in the Watch app on the iPhone, we see a spinner for about 1 second and then a silent failure, with the button reverting back to “Install”.
This is occurring with other apps purchased through VPP. We purchased the CityMapper app through VPP, assigned it to a supervised iPhone, and attempted to install CityMapper's watchOS companion app and got the same failed result.
This is NOT occurring on a clean & reset supervised iPhone and its paired watch running iOS 17.3.1 / watchOS 10.3.
On a personal unsupervised device running iOS 17.4/watchOS 10.4 with a copy of our app purchased through the App Store, installing the watchOS companion app is not an issue.
I filed radar FB13687404 but in 10 years of developing for iOS, I have never ever ever heard of Apple responding to one of those. Posting here in the hope that other users/developers can share their issues or solutions.
Hi everyone,
We have a sports app that helps track your game scores. Still, when you are in the middle of a game and receive a notification (e.g., an activity notification, a WhatsApp or third-party app), that notification will pop up on the screen, overlapping the app. This forces you to scroll all the way down the notification and close it before you can continue using the app.
Some users are complaining about this, and it's indeed very annoying. I was wondering if there's any way to control that during matches, no notifications pop up on your screen (it's ok to have the red dot on top, but having the notification overlapping is what kills the app's usability).
Users can avoid this by choosing the right "focus" mode before starting a new match. However, many don't even know this feature exists or how to deal with it.
Is there any way to block incoming notifications from appearing on the screen while the app is being executed?
Hello
Do we have access to the ECG raw data on the apple watch?
I was able to access the data using HKElectrocardiogram Class API. "ecgSample" returns all the recorded ECG logs done by the user using the default apple app.
I want to access the data in real-time, do the API supports that? That is, I want to create a custom app in which I direct the user towards recording an ecg signal and then do whatever I want with it.
Please let me know, that would be very helpful!
In iPhone, if you open Files app and tap on an associated file type, its corresponding app is launched. I have implemented this functionality in my iOS SwiftUI app - associated a file type - .csk, with my iOS app and handled its launch using the onOpenURL(perform:) modifier.
WindowGroup {
FileContentView()
.onOpenURL(perform: { (fileUrl: URL) in
Log(String(format: "File Url = %@", fileUrl.absoluteString))
// Update UI with the content of the file
})
}
I want to achieve the same for my watchOS app. I noticed that the UTExportedTypesDeclaration key, which is used to declare the file types created and owned by the app, is not available for watchOS. But the CFBundleDocumentTypes key, which is used to associate a file type with the app is available. So, I expect my app to respond to taps on those associated file types, but I've run into a snag. There is no Files app in AppleWatch nor is there a way to view my iCloud storage. I have my .csk file (which is associated with the watchOS app) in iCloud.
So, how can I test this launch? How can an AppleWatch user tap a file and view it in his app? It should be possible to handle file launches since CFBundleDocumentTypes is available for watchOS.
Hello,
The Apple Watch's connectivity to Xcode has always been finicky. Sometimes it would start doing "transport errors" and you'd have to repair the watch/phone to xcode to resolve it. Now after the 10.4 upgrade, it seems that there are cases where the watch doesn't even show in the device list. Here's what I've observed:
The watch will connect the first time you launch xcode(after 10.4 install or a new restore).
If you unpair the watch, it will never show in the device list again. This is despite any remediation efforts, such as unpairing the phone from xcode, restarting the watch/phone, and clearing trusted devices.
Erasing the watch and restoring it will allow it to connect again to xcode, but only if you never unpair it. If you unpair the watch, it will repeat the behavior of not showing in the device list again.
So, the only solution is to erase/restore the watch to get it to show in the device list on xcode. Every single time.
Again, this is new behavior for Watch OS 10.4
I got a new MacBook and set it up as a new one, not transferring any data from the old one.
But now the Apple Watch (Series 6) paired with my iPhone (14 Pro Max) ist not shown in Xcode.
iPhone and Watch are using the latest RC and also Xcode is the latest RC.
But in Xcode I ca only see my iPhone, not the paired Watch.
See Screenshots. The first shows the new MacBook and the second the old one.
I already tried a lot, but nothing helps:
Unpair Watch from Phone and then pair it again
Plug the iPhone to different USB ports
Restart Watch, iPhone and Mac
Delete the iPhone from Xcode
Enable and disable Developer Mode on iPhone and Watch
What else can I try to get the Watch back?
We have a watch app, that contains TabView with two child views.
First Child View have a slider control that supports digitalCrownRotation.
Second child view have a normal text on the screen “Hello”
When app is launched, the slider in the first view got highlighted when user rotates the Digital Crown but when we moved to Second tab and navigate back to first view, and rotates the Digital Crown, the slider view never gets highlighted but the value of Slider gets changed and value gets changed by any step.
This issue was introduced after WatchOS 10.2. Prior to WatchOS10.2 everything worked fine.
Could you please assist me to find the solution to resolve this issue?
Hi all,
I am trying to build an app which, on support Apple Watch's (currently just the Ultra's), will detect when the watch has been submerged and will start to report temperature from the sensor.
I have followed the developer articles I could find around CMWaterSubmersionManager and have set up a simple class to interact with it.
It is now that I want to run my app and test if it is working as I expect it to etc. However I noticed that the waterSubmersionAvailable is only set to true on physical Apple Watch Ultra and Ultra 2. This is rather inconvenient as it means that for the next week or so while developing this feature I will have to stick my arm wearing the watch into a container of water to test the feature.
Just wondering if there is any easier way to debug this stuff that anyone has figured out? It would be ideal if this could just be done in the simulator similar to how other device conditions can be induced.
I did notice the "Enable Easy Submersion" option in the Debug menu, however I could not figure out a difference between having this on or off, and could not find any explanation of what it actually does on the docs. Does anyone have any experience with this either?
Any advice would be appreciated, and to any Apple engineers who may see this, please please please add an option to be able to debug this stuff in the Simulator