Hello,
We are trying to implement Actionable Notifications on iOS via Remote Notifications.
According to Apple’s official documentation (Declaring Your Actionable Notification Types),
it is recommended to register notification categories at launch time.
However, in our use case, the number of buttons and their actions in the Actionable Notification are determined at the time of the Remote Notification request.
This means that we cannot predefine the categories at app launch but need to dynamically configure them based on the payload of the Remote Notification.
Our Approach
We are considering setting aps.mutable-content = 1 and using Notification Service Extension to modify the categoryIdentifier dynamically.
Below is the JSON payload we plan to use for Remote Notifications:
{
"aps": {
"alert": {
"title": "New Message Received!",
"body": "Check out the details."
},
"category": "DYNAMIC_CATEGORY",
"mutable-content": 1
},
"categoryData": {
"id": "DYNAMIC_CATEGORY",
"actions": [
{
"id": "REPLY_ACTION",
"title": "Reply",
"options": ["foreground"]
},
{
"id": "DELETE_ACTION",
"title": "Delete",
"options": ["destructive"]
}
]
}
}
Questions:
Can we dynamically configure Actionable Notifications based on the Remote Notification payload?
If we set categoryIdentifier in Notification Service Extension’s didReceive(_:withContentHandler:), will users still see the correct action buttons even if the app is terminated?
What is the recommended approach to dynamically configure Actionable Notifications at the time of receiving the Remote Notification, rather than at app launch?
Delve into the world of built-in app and system services available to developers. Discuss leveraging these services to enhance your app's functionality and user experience.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
As of iOS 18.3 SDK, Core Bluetooth is still mostly an Objective-C framework: key objects like CBPeripheral inherit from NSObjectProtocol and does not conform to Sendable.
CBCentralManager has a convenience initializer that allows the caller to provide a dispatch_queue for delegate callbacks. I want my Swift package that implements Core Bluetooth to conform to Swift 6 strict concurrency checking.
It is unsafe to dispatch the delegate events onto my own actor, as the passed in objects are presumably not thread-safe. What is the recommended concurrency safe way to implement Core Bluetooth in Swift 6 with strict concurrency checking enabled?
We are looking to setup domain-bound codes for our app and need to add the associated domain file to our website.
We currently do not use Universal Links or Password AutoFill.
We have looked at the documentation but are not sure of what the contents of the association file should be to enable domain-bound codes if you are not using Universal Links or Password AutoFill.
Can any assistance be provided?
While troubleshooting Tap to Pay on iPhone, it is essential that the developer is able to collect logs on their device and check those logs for error messages. This is also essential when reporting issues to Apple. To gather the required data for your own debugging as well as reporting issues, please perform the following steps on the test device:
Install the Tap to Pay profile on your iPhone.
Reproduce the issue and make a note of the timestamp when the issue occurred, while optionally capturing screenshots or video.
Gather a sysdiagnose on the same iPhone.
Create a Feedback Assistant report with the following information:
The bundle ID
The serial number of the device.
For iOS, open Settings > General > About (tap and hold to copy).
The SEID (Secure Element Identifier) of the device, represented as a HEX encoded string.
For iOS, open Settings > General > About > SEID (tap and hold to copy).
The sysdiagnose gathered after reproducing the issue.
The timestamp (including timezone) of when the issue was reproduced.
Screenshots or videos of errors and unexpected behaviors (optional).
Submitting Your Feedback
After your submission to Feedback Assistant is complete, please respond to your post with the Feedback ID. Once received, I can begin my investigation and determine if this issue is caused by an error within your app, a configuration issue within your developer account, app configuration, or an underlying system bug.
Cheers,
Paris X Pinkney | WWDR | DTS Engineer
Hi, I want to open an email message with AppleScript. Everything is working correctly, but in the Mail app, instead of focusing on targetMessage, it highlights the email after the target message.
When I use:
tell targetMessage to open
the correct email opens in new window but the wrong email is highlighted in the Mail app list.
tell application "Mail"
activate
set targetAccount to missing value
repeat with anAccount in every account
if name of anAccount is "AccountName" then
set targetAccount to anAccount
exit repeat
end if
end repeat
if targetAccount is not missing value then
set targetBox to missing value
repeat with aBox in mailboxes of targetAccount
if name of aBox is "MailboxName" then
set targetBox to aBox
exit repeat
end if
end repeat
if targetBox is not missing value then
set targetMessage to missing value
set oneWeekAgo to (current date) - (7 * days)
set filteredMessages to (every message of targetBox whose date received ≥ oneWeekAgo)
repeat with aMessage in filteredMessages
try
if message id of aMessage is "MessageID" then
set targetMessage to aMessage
exit repeat
end if
end try
end repeat
if targetMessage is not missing value then
if (count of message viewers) > 0 then
set mailViewer to message viewer 1
else
set mailViewer to make new message viewer
end if
tell mailViewer
set selected mailboxes to {targetBox}
delay 0.2
set selected messages to {targetMessage}
end tell
return "Found"
else
return "Message Not found"
end if
else
return "Folder Not found"
end if
else
return "Account Not found"
end if
end tell
Why is this behavior happening?
I am able to get location in for ground and back ground but
Now I need to get location when user killed app.
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
Watch Connectivity
watchOS
Core Location
I am developing a macOS non-interactive macOS application which does not show any ui.
i want to block main thread and do all the work on worker thread . Once done with work in worker thread, want to unblock main thread by exiting event loop to terminate application.
Because i dont want to show any UI or use any Foundation/Cocoa functionality, i am thinking of using CFRunLoop to block main thread from exiting until i finish my work in worker thread.
When i tried this in a project, I am able to finish work in worker thread after block main thread using CFRunLoop.
I also want this application to be a bundled application, which can be launched by double clicking on application bundle . But when i tried it in my xcode project by launching it using double clicking on application bundle, application keeps on toggling/bouncing in the dock menu with a status "Not responding". Although i am able to complete my work in worker thread.
import Foundation
let runLoop = CFRunLoopGetCurrent()
func workerTask() {
DispatchQueue.global().async {
print("do its work")
sleep(5) // do some work
print("calling exit event loop")
CFRunLoopStop(runLoop)
print ("unblocking main thread")
}
}
workerTask ()
// blocking main thread
print ("blocked main thread")
CFRunLoopRun()
print ("exit")
Why i am getting this application bouncing in doc menu behavior ? I tried by using NSApplicationMain instead of CFRunLoop in my project, in that case i didnt get this behavior .
Does NSApplicationMain does some extra work before starting NSRunLoop which i am not doing while using CFRunLoop, which is showing this toggling/Bouncing application icon in Dock menu ?
or Is this bouncing app icon issue is related to run loop i am using which is CFRunLoop ?
Note : If i dont use a bundled application and use a commandline application then i am able to do all steps in worker thread and exit main thread as i wanted after finishing my work . But i need to do all this in application which can be launched using double clicking (bundled applcation).
If not by using CFRunLoop, then how can i achive this ? - Create a application which shows no UI and do all work in worker thread while main thread is blocked. Once work is done unblock main thread and exit. And user should be able to launch application using double click the application icon.
Hi , how I can run my shortcut by tapping on button from widget?
we’re looking to get some clarification around how the hourly forecasts should be interpreted to ensure we’re using your data in the correct manner. If you could provide the answers to the following questions would be extremely helpful:
1. What do the data points (e.g temperature) in the hourly forecast represent for a future hour? Do they represent the expected average over that future hour or do they represent the forecast for the point in time at the top of the hour?
2. What do those same data points represent in the hourly forecast for an hour which has already begun? e.g. it’s 8:30 and we pull the hourly forecast and the 8:00 hour is still returned. Which of the following would be the correct interpretation for the values returned for the 8:00 hour:
The values represent the forecast for the point in time at the top of the 8:00 hour (if this is the case we would expect it to stop updating)
The values represent the current forecast i.e. what the weather is right now
The values represent the average over the remaining portion of the 8:00 hour
The values represent the average over the full 8:00 hour including both the portion which has already elapsed and the portion which is still to come
3. What does the data represent after the hour (i.e. looking at historical hours)? Is it:
The last forecast made within the hour? If so, is that point-in-time or average for the hour (as explained above)?
The actual weather for that hour (using some non-forecast measure of real weather)? If so, again is that point-in-time at top of hour / point-in-time at end of hour / average over the hour?
Hello all,
I have run into a weird situation in my watchOS app with a companion iOS app.
Issue: Watch fails to receive sendMessage string sent from phone while watch is in foreground. This is not consistent and seems to happen randomly under certain conditions.
Order of operations: User Opens phone app & watch app -> user presses "sendMessage" button, func is called -> watch does not receive message while in foreground
Condition explanation: To my knowledge, without a HealthKit workout session active, the apple watch is not available to receive messages (using any internal library transmission type) from its iOS companion app while the watch screen is not in the foreground (i.e. inactive). However, my issue is that sometimes, while the watch IS in the foreground, it does not receive the companion app's message. Additionally, this is not resolved by force quitting both iOS and watchOS apps. The only way I have gotten this issue to go away is by restarting both the phone and the watch. Again, it is not a consistent behavior and seemingly happens randomly. This behavior has been observed across multiple different beta testers on different hardware.
This is only apparent when transmitting from Phone -> Watch. I have not experienced any transmission issues when transmitting Watch -> Phone.
My team and I have speculated that it could be an issue with WCSession.isReachable returning true before we transmit the message but changing to false before the hardware actually transmits. However, this wouldn't explain why the watch would not be available while in the foreground. This is just a preliminary thought.
My goal in posting on here is to see if anyone else has experienced this, or if it's a known bug.
All message protocols have been coded to follow Apple's WCSession documentation as closely as possible.
Hardware specs:
Watch Model: A2093 (series 5)
WatchOS ver: 10.6.1
Phone: MU693LL/A (15 pro max)
iOS ver: 18.3.2
XCode ver: 16.0
Hi,
Need input on making ICEcard app paid version , requirements. The app is presently live for India and shortly will be for global. This app is for primary health information which is critical in case anyone faces emergency. Will it have any regulatory concerns ?
https://apps.apple.com/in/app/ice-card-app/id6736453602
Topic:
App & System Services
SubTopic:
Health & Fitness
I ran into a problem. When using Storekit1 to purchase an SKU, the user payment was successful, but StoreKit1 did return paymentCancelled to my App. I would like to know under what circumstances this problem may occur? How do I fix it? Thank you
Our app receives real-time GPS and aircraft data from devices via UDP broadcast and/or multicast on a WiFi network created by the device.
We have identified that the iPhone or iPad will just stop receiving UDP broadcast/multicast data for an interval of time. In general, it appears after roughly every 128KB of data is received.
In the attached screenshot from Xcode instruments, you can see the data reception alternating on/off.
We have verified with Wireshark that the data is still flowing during that entire time period. And by tracking bytes received the app ultimately receives about 55% of the bytes, which tracks with the Network graph.
We have used different approaches to the network code, including GCDAsyncUdpSocket, BSD Sockets, and the Network framework. We've tried it on background threads and the main thread. Tested it on iPads and iPhones. All produce the same result. The data is just never reaching the app code.
Any insight on what may be temporarily disabling data reception?
I am trying to convert a simple URLSession request in Swift to using NWConnection. This is because I want to make the request using a Proxy that requires Authentication. I posted this SO Question about using a proxy with URLSession. Unfortunately no one answered it but I found a fix by using NWConnection instead.
Working Request
func updateOrderStatus(completion: @escaping (Bool) -> Void) {
let orderLink = "https://shop.ccs.com/51913883831/orders/f3ef2745f2b06c6b410e2aa8a6135847"
guard let url = URL(string: orderLink) else {
completion(true)
return
}
let cookieStorage = HTTPCookieStorage.shared
let config = URLSessionConfiguration.default
config.httpCookieStorage = cookieStorage
config.httpCookieAcceptPolicy = .always
let session = URLSession(configuration: config)
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField: "Accept")
request.setValue("none", forHTTPHeaderField: "Sec-Fetch-Site")
request.setValue("navigate", forHTTPHeaderField: "Sec-Fetch-Mode")
request.setValue("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15", forHTTPHeaderField: "User-Agent")
request.setValue("en-US,en;q=0.9", forHTTPHeaderField: "Accept-Language")
request.setValue("gzip, deflate, br", forHTTPHeaderField: "Accept-Encoding")
request.setValue("document", forHTTPHeaderField: "Sec-Fetch-Dest")
request.setValue("u=0, i", forHTTPHeaderField: "Priority")
// make the request
}
Attempted Conversion
func updateOrderStatusProxy(completion: @escaping (Bool) -> Void) {
let orderLink = "https://shop.ccs.com/51913883831/orders/f3ef2745f2b06c6b410e2aa8a6135847"
guard let url = URL(string: orderLink) else {
completion(true)
return
}
let proxy = "resi.wealthproxies.com:8000:akzaidan:x0if46jo-country-US-session-7cz6bpzy-duration-60"
let proxyDetails = proxy.split(separator: ":").map(String.init)
guard proxyDetails.count == 4, let port = UInt16(proxyDetails[1]) else {
print("Invalid proxy format")
completion(false)
return
}
let proxyEndpoint = NWEndpoint.hostPort(host: .init(proxyDetails[0]),
port: NWEndpoint.Port(integerLiteral: port))
let proxyConfig = ProxyConfiguration(httpCONNECTProxy: proxyEndpoint, tlsOptions: nil)
proxyConfig.applyCredential(username: proxyDetails[2], password: proxyDetails[3])
let parameters = NWParameters.tcp
let privacyContext = NWParameters.PrivacyContext(description: "ProxyConfig")
privacyContext.proxyConfigurations = [proxyConfig]
parameters.setPrivacyContext(privacyContext)
let host = url.host ?? ""
let path = url.path.isEmpty ? "/" : url.path
let query = url.query ?? ""
let fullPath = query.isEmpty ? path : "\(path)?\(query)"
let connection = NWConnection(
to: .hostPort(
host: .init(host),
port: .init(integerLiteral: UInt16(url.port ?? 80))
),
using: parameters
)
connection.stateUpdateHandler = { state in
switch state {
case .ready:
print("Connected to proxy: \(proxyDetails[0])")
let httpRequest = """
GET \(fullPath) HTTP/1.1\r
Host: \(host)\r
Connection: close\r
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15\r
Accept-Language: en-US,en;q=0.9\r
Accept-Encoding: gzip, deflate, br\r
Sec-Fetch-Dest: document\r
Sec-Fetch-Mode: navigate\r
Sec-Fetch-Site: none\r
Priority: u=0, i\r
\r
"""
connection.send(content: httpRequest.data(using: .utf8), completion: .contentProcessed({ error in
if let error = error {
print("Failed to send request: \(error)")
completion(false)
return
}
// Read data until the connection is complete
self.readAllData(connection: connection) { finalData, readError in
if let readError = readError {
print("Failed to receive response: \(readError)")
completion(false)
return
}
guard let data = finalData else {
print("No data received or unable to read data.")
completion(false)
return
}
if let body = String(data: data, encoding: .utf8) {
print("Received \(data.count) bytes")
print("\n\nBody is \(body)")
completion(true)
} else {
print("Unable to decode response body.")
completion(false)
}
}
}))
case .failed(let error):
print("Connection failed for proxy \(proxyDetails[0]): \(error)")
completion(false)
case .cancelled:
print("Connection cancelled for proxy \(proxyDetails[0])")
completion(false)
case .waiting(let error):
print("Connection waiting for proxy \(proxyDetails[0]): \(error)")
completion(false)
default:
break
}
}
connection.start(queue: .global())
}
private func readAllData(connection: NWConnection,
accumulatedData: Data = Data(),
completion: @escaping (Data?, Error?) -> Void) {
connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, context, isComplete, error in
if let error = error {
completion(nil, error)
return
}
// Append newly received data to what's been accumulated so far
let newAccumulatedData = accumulatedData + (data ?? Data())
if isComplete {
// If isComplete is true, the server closed the connection or ended the stream
completion(newAccumulatedData, nil)
} else {
// Still more data to read, so keep calling receive
self.readAllData(connection: connection,
accumulatedData: newAccumulatedData,
completion: completion)
}
}
}
Hi,
I’m trying to perform UWB ranging between an iPhone and a Qorvo DWM3001CDK accessory using Apple NI’s NINearbyAccessoryConfiguration class. I’ve followed the steps described in the official Apple documentation (https://developer.apple.com/documentation/nearbyinteraction/ninearbyaccessoryconfiguration), specifically for enabling background mode using the init(accessoryData:bluetoothPeerIdentifier:) initializer.
The configuration is successfully created, and background mode is enabled. However, when the iPhone starts the session, I doesn’t receive any ranging data from the DWM3001CDK, and the session ends with a timeout.
Interestingly, if I use the init(data:) initializer, I can successfully receive ranging data, but this only works in foreground mode, which doesn’t meet my requirements.
Steps I’ve followed:
Used Core Bluetooth to discover and pair the accessory.
Retrieved the configuration data from the accessory according to the third-party UWB device specifications.
Initialized the configuration using NINearbyAccessoryConfiguration(accessoryData:bluetoothPeerIdentifier:) for background mode.
Started the session with NISession.run(configuration).
Waited for updates in the delegate method session(_:didUpdate:).
Specific questions:
Are there additional requirements for using init(accessoryData:bluetoothPeerIdentifier:) to enable background UWB ranging with the DWM3001CDK?
Is there a known difference in how init(data:) and init(accessoryData:bluetoothPeerIdentifier:) handle the ranging process?
Any advice or insights would be greatly appreciated.
Thanks in advance!
Hey there my application allows users to have video calls with each other using Agora. I have successfully set up incoming call functionality on Android but on iOS I am struggling to get the call ui to appear when the app is not running/in background/locked.
To my knowledge this is because there is much stricter security on iOS which is limiting me from calling this. When i initially set it up it worked at first when the app was in the background but I think I was failing to report the call to call kit in time and now it's not working.
I'm not sure if I need access to this entitlement:
com.apple.developer.pushkit.unrestricted-voip
Which i believe is only for the big boys or if I make sure I'm reporting the call to call kit fast enough that I won't encounter this issue and it will consistently work in the background.
According to my experiments SwiftData does not work with model attributes of primitive type UInt64. More precisely, it crashes in the getter of a UInt64 attribute invoked on an object fetched from the data store.
With Core Data persistent UInt64 attributes are not a problem. Does anyone know whether SwiftData will ever support UInt64?
I've created an OpenIntent with an AppEntity as target.
Now I want to receive this entity when the intent is executed and the app is opened. How can I do that?
I can't find any information about it and there are no method for this in the AppDelegate
Here is an AppleScript script to make it possible double-click files in Finder so that they will be opened in Vim, by Normen Hansen: https://github.com/normen/vim-macos-scripts/blob/master/open-file-in-vim.applescript (it must be used from Automator).
I try to simplify it and also to make it possible to use it without Automator. To use my own version, you only need to save it as application instead, like this:
osacompile -o open-with-vim.app open-with-vim.applescript
and then copy it to /Applications and set your .txt files to be opened using this app.
Here it is, it alsmost works:
-- https://github.com/normen/vim-macos-scripts/blob/master/open-file-in-vim.applescript
-- opens Vim with file or file list
-- sets current folder to parent folder of first file
on open theFiles
set command to {}
if input is null or input is {} or ((item 1 in input) as string) is "" then
-- no files, open vim without parameters
set end of command to "vim;exit"
else
set firstFile to (item 1 of theFiles) as string
tell application "Finder" to set pathFolderParent to quoted form of (POSIX path of ((folder of item firstFile) as string))
set end of command to "cd" & space & (pathFolderParent as string)
set end of command to ";hx" -- e.g. vi or any other command-line text editor
set fileList to {}
repeat with i from 1 to (theFiles count)
set end of fileList to space & quoted form of (POSIX path of (item i of theFiles as string))
end repeat
set end of command to (fileList as string)
set end of command to ";exit" -- if Terminal > Settings > Profiles > Shell > When the shell exits != Don't close the window
end if
set command to command as string
set myTab to null
tell application "Terminal"
if it is not running then
set myTab to (do script command in window 1)
else
set myTab to (do script command)
end if
activate
end tell
return
end open
The only problem is the if block in the very beginning:
if input is null or input is {} or ((item 1 in input) as string) is "" then
What is wrong here? How to make it work? (Assuming it already works fine if AppleScript is used using Automator.)
So i created an App and for some time it was working fine. The app has features to show pdf to users without logging in. I needed to upload all data to cloudkit on public database.
I was not having knowledge that there are 2 mode being a noob in coding so after i saved all records in development mode in cloudkit when i published my app, i was not able to see them (Reason because live mode works in Production mode).
So i need help now to transfer data from development mode to production mode or any app or code that can help me upload all data in production mode.
Topic:
App & System Services
SubTopic:
iCloud & Data
Tags:
CloudKit
CloudKit Dashboard
CloudKit Console