Post not yet marked as solved
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
Post not yet marked as solved
如何自定义开发表盘模版,不是表盘组件,比如设置背景图片,调整各个表盘组件的位置
Post not yet marked as solved
手表系统: 10.2
表现:从手机Watch App上看,表盘组件部分都显示关闭;从手表上看,表盘组件不展示
Post not yet marked as solved
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)
}
}
}
Post not yet marked as solved
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()
}
}
Post not yet marked as solved
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.
Post not yet marked as solved
I am a watchOS 10.0 device, try to open the developer mode, according to the official website to enter the Settings > Privacy > Developer Mode. But I don't see the developer mode option, how do I turn on the developer mode for watchOS 10.0 device?
Post not yet marked as solved
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 !
Post not yet marked as solved
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?
Post not yet marked as solved
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.
Post not yet marked as solved
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?
Post not yet marked as solved
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.
Post not yet marked as solved
I currently have an app that is a companion app alongside the iOS app. I wonder if it is possible for me to make this app both a standalone and a companion app. Essentially if someone does not have an iphone they can still use the app. Is this possible?
Post not yet marked as solved
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()
}
Post not yet marked as solved
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
Post not yet marked as solved
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.
Post not yet marked as solved
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.
Post not yet marked as solved
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?
Post not yet marked as solved
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?
Post not yet marked as solved
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?