With the introduction of the Tides app in watchOS 11, users can now view information about tides and swells along the coast. Is this data accessible to developers via WeatherKit?
In the Tides app, the data source for tides and weather is shown as WeatherKit.
General
RSS for tagDelve 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.
Post
Replies
Boosts
Views
Activity
I recently published a new version of my app (I'm fairly new to this) once it was marked ready for distribution I can see it updated in App Store and it allowed me to update. but when I open the app my previous launch screen is present then the screen gos white and stalls.
what did I do wrong
I'm using WeatherKit for my weather app built with SwiftUI. Even though the location is set in an area where the NWS is issuing weather alerts, WeatherKit randomly returns availability.alertAvailability as temporarilyUnavailable or unsupported, and the weatherAlerts is always nil.
I'd like to be able to invoke an App Clip from an Apple Pass notification. I've been using an Apple Pass store card successfully. Ideally, I'd like to be able to tap the notification to open the App Clip.
I haven't seen support for this in the documentation, but I wanted to see if anyone had any creative use cases for something like this?
Hi devs,
my app has control center widgets and interactive widgets, both are using the same app intent to update sharing status (App Group's UserDefault).
When the app is running in the background, control center widget and interactive widgets can be reloaded with correct status. However, if the app is not running in the background, I tap the interactive widget and the interactive widget can reload with correct status but the control center widget can't. Vice versa, the control center widgets can reload with correct status but the interactive widgets can't.
struct ChangeAppStatusIntent: AudioRecordingIntent, CustomIntentMigratedAppIntent, PredictableIntent, LiveActivityIntent, SetValueIntent {
... // data and setup
@MainActor
func perform() async throws -> some IntentResult {
// change the AppGroup data for app status
WidgetCenter.shared.reloadAllTimelines()
ControlCenter.shared.reloadAllControls()
}
}
does any way to fix this issue?
Hello,
I've been encountering some challenges while working with NWConnectionGroup and NWMulticastGroup for multicast operations on iOS. I have a few doubts and issues that I would like to address:
1. NWMulticastGroup Initialization
It seems that when initializing NWMulticastGroup, only one NWEndpoint can be passed, and attempting to pass multiple endpoints results in failure. Can someone confirm if this behavior is correct?
2. Interface Level Control
Upon initializing NWConnectionGroup, it appears that packets are received on all interfaces without the ability to control this at the interface level. Is this correct? If not is there a way to configure NWConnectionGroup to receive packets on all interfaces?
3. Sending Behavior
During the send operation, it appears that the data is sent through any one of the available interfaces, and there doesn't seem to be an option to configure it to send through all available endpoints. Is there a way to enable sending data through all available endpoints?
Any insights, guidance, or solutions to these issues would be greatly appreciated. Has anyone else encountered similar problems or found workarounds for these limitations?
Thank you for your assistance and support.
Thanks,
Harshal
Our team has recently added support to our app for Live Activities where the source of the data is driven from the app itself (not push notifications).
We've noticed a crash happening in our core data code caused by the following error thrown by the addPersistentStore function where it would attempt to recover and eventually crash. Here's an error we created to help us debug that contains the error details:
Domain: CoreData Code: 1 NSLocalizedDescription: Error performing migration for databaseName=mydb.sqlite. Error details=The file couldn’t be saved because you don’t have permission. - userinfo: ["reason": No permissions to create file; code = 1]
After some trouble shooting, we managed to reproduce the issue by doing a hard reboot while we're running a live activity. It appears that when the device starts back up, the Live Activity starts which triggers the app to hit didFinishLaunchingWithOptions which is where we get our Core Data store initialized.
The problem is that our app uses Data Protection using NSFileProtectionCompleteUntilFirstUserAuthentication and we'd prefer to keep it that way.
The Core Data db is present in the app sandbox and we're also seeing logs to suggest a failure trying to access NSUserDefaults as well.
Is there an accepted solution for this? Is it expected that a Live Activity would cause an application to launch prior to the device being unlocked for the first time? Is there a way to change that?
Hi, so, we grabbed a couple of nice new watches the other week (Ultra for dad, SE for teenage son). Mostly cool and working together (calls, messages, maps, walkie talkies, etc, etc). All good.
But then son said, "Dad, why can't I see my sleep stuff like you can..?". He was right, it wasn't working. Looking around a bit, it turns out that there are a bunch of things that are turned off or not available when pairing a kids watch with dad's phone.
From the Apple page: "The following features and apps are not available: Medications, respiratory rate, irregular heart rhythm notifications, ECG, AF History, Cycle Tracking, Sleep, Wrist Temperature, Blood Oxygen, Walking Steadiness, Audiobooks, Remote, News, Shortcuts and the double-tap gesture".
Now dev-me reacts to this situation with: "Ok, so let's just build a little standalone sleep app for son's watch. There must be lots of parents out there who would like the same thing". And there are also a bunch of other "family sharing" enabled apps that when you try and use them on kid's phone, say "iPhone requireed", i.e, they don't apparently work with just a watch hooked up to mum or dad's phone.
So before I dive into that kind of project, which seems like an obvious fix path from a dev and a parents' point of view: does anybody know if this from Apple's point of view is a hardware, a software or a legal/age limitation? What's the basic framework/dev/design issue here?
Is it something on the device(s) that prevents sleep data from even being collected on family/kids paired watches? (Therefore don't bother trying to build an app); I assume not becauses it's just a normal SE used by a kid; or
Is it "just" that Apple hasn't wanted to make that available without a kids iPhone too (Therefore you could certainly build a standalone app to do what Apple hasn't wanted to do); or
Netiher 1 nor 2, but Apple won't even allow Sleep data collection for kids for some legal/health data reason (Therefore don't bother trying to build the app).
A Swift MacOS works with no problem on Intel or ARM Macs (from 11, BigSur to 15, Sequoia) but recently I learned that is crashes when launched on a Mac which language is set to French.
I'm not saying this setting is causing the issue, but is the most obvious difference observed compared to many other Macs where the App runs with no problem.
The crash occurred in a MacOS intel. See excerpts from crash report below:
Process: MySwiftAPP [626]
Path: /Volumes/VOLUME/*/MySwiftAPP.app/Contents/MacOS/MySwiftAPP
Identifier: Myinfo.MYSwiftAPP
Version: X.Y.01 (1)
Code Type: X86-64 (Native)
Parent Process: launchd [1]
User ID: 501
Date/Time: 2021-01-05 01:47:12.0578 +0100
OS Version: macOS 12.2.1 (21D62)
Report Version: 12
Bridge OS Version: 3.0 (14Y910)
Anonymous UUID: 3579800E-84CC-15C4-2981-320ECF2E1400
Time Awake Since Boot: 62 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace SIGNAL, Code 4 Illegal instruction: 4
Terminating Process: exc handler [626]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 MySwiftAPP 0x10c6df5bb 0x10c61d000 + 796091
1 MySwiftAPP 0x10c6be4dc 0x10c61d000 + 660700
2 SwiftUI 0x7ff919a8ff0e closure #1 in AppearanceActionModifier.MergedBox.update() + 72
3 SwiftUI 0x7ff9193d2047 thunk for @escaping @callee_guaranteed () -> () + 12
4 SwiftUI 0x7ff919a91012 partial apply for thunk for @escaping @callee_guaranteed () -> () + 17
5 SwiftUI 0x7ff919bbc028 closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 2414
6 SwiftUI 0x7ff919ba9fbe ViewRendererHost.render(interval:updateDisplayList:) + 359
7 SwiftUI 0x7ff919c04d56 closure #1 in NSHostingView.layout() + 126
8 SwiftUI 0x7ff919c0dce7 partial apply for thunk for @callee_guaranteed (@guaranteed NSAnimationContext) -> () + 17
9 SwiftUI 0x7ff919c023fd thunk for @escaping @callee_guaranteed (@guaranteed NSAnimationContext) -> () + 36
10 AppKit 0x7ff8113fa152 +[NSAnimationContext runAnimationGroup:] + 55
11 SwiftUI 0x7ff919c04c8a NSHostingView.layout() + 287
12 SwiftUI 0x7ff919c0508a @objc NSHostingView.layout() + 21
13 AppKit 0x7ff811435d7f NSViewLayout + 564
14 AppKit 0x7ff811435851 -[NSView layoutSubtreeWithOldSize:] + 352
15 AppKit 0x7ff811434d68 -[NSView layoutSubtreeIfNeededAndAllowTemporaryEngine:] + 1041
16 AppKit 0x7ff811677f22 +[NSWindow windowWithContentViewController:] + 57
17 SwiftUI 0x7ff9199cd634 specialized WindowStyle.makeWindow(:) + 42
18 SwiftUI 0x7ff919b6c724 AnyWindowStyleStorage.makeWindow(:) + 26
19 SwiftUI 0x7ff91974a736 AppWindowsController.makeWindowController(:restorationID:environment:) + 2314
20 SwiftUI 0x7ff91974887d AppWindowsController.makeMainWindow(info:) + 66
21 SwiftUI 0x7ff9197487c7 AppWindowsController.makeMainWindow() + 424
22 SwiftUI 0x7ff919748067 AppWindowsController.showInitialMainWindow() + 82
23 SwiftUI 0x7ff9194e0c3e AppDelegate.applicationDidFinishLaunching(:) + 85
24 SwiftUI 0x7ff9194e0dd6 @objc AppDelegate.applicationWillFinishLaunching(_:) + 114
25 CoreFoundation 0x7ff80e9a6f23 CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 12
26 CoreFoundation 0x7ff80ea443f9 ___CFXRegistrationPost_block_invoke + 49
27 CoreFoundation 0x7ff80ea44376 _CFXRegistrationPost + 496
28 CoreFoundation 0x7ff80e978836 _CFXNotificationPost + 733
29 Foundation 0x7ff80f7c01be -[NSNotificationCenter postNotificationName:object:userInfo:] + 82
30 AppKit 0x7ff8113e761b -[NSApplication _postDidFinishNotification] + 305
31 AppKit 0x7ff8113e736d -[NSApplication _sendFinishLaunchingNotification] + 208
32 AppKit 0x7ff8113e4f40 -[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:] + 541
33 AppKit 0x7ff8113e4b97 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 665
34 Foundation 0x7ff80f7eb194 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 308
35 Foundation 0x7ff80f7eb006 _NSAppleEventManagerGenericHandler + 80
36 AE 0x7ff815043d28 0x7ff815038000 + 48424
37 AE 0x7ff815043592 0x7ff815038000 + 46482
38 AE 0x7ff81503c9c7 aeProcessAppleEvent + 419
39 HIToolbox 0x7ff8175fdc42 AEProcessAppleEvent + 54
40 AppKit 0x7ff8113df222 DPSNextEvent + 2064
41 AppKit 0x7ff8113dd3f4 -[NSApplication(NSEvent) nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1411
42 AppKit 0x7ff8113cf919 -[NSApplication run] + 586
43 AppKit 0x7ff8113a37b7 NSApplicationMain + 816
44 SwiftUI 0x7ff9191dad3f specialized runApp(:) + 161
45 SwiftUI 0x7ff919bf9c84 runApp(:) + 164
46 SwiftUI 0x7ff91970191f static App.main() + 63
47 MySwiftAPP 0x10c6be9ae 0x10c61d000 + 661934
48 dyld 0x1134d64fe start + 462
Thread 1:
0 libsystem_pthread.dylib 0x7ff80e8e5fec start_wqthread + 0
Thread 0 crashed with X86 Thread State (64-bit):
rax: 0x0000000200000003 rbx: 0x00007f8db5915210 rcx: 0xfffffffe00000000 rdx: 0x0000000000000003
rdi: 0x00007f8db586b178 rsi: 0x00007ff8518bbf58 rbp: 0x00007ff7b38e0080 rsp: 0x00007ff7b38e0000
r8: 0x0000000000000002 r9: 0x80000000ffffffff r10: 0xfffffffe00000000 r11: 0x0000000000000001
r12: 0x00007f8db586b170 r13: 0x00007f8db586bb40 r14: 0x00007f8db586b290 r15: 0xe800000000000000
rip: 0x000000010c6df5bb rfl: 0x0000000000010297 cr2: 0x00007ff8510288e8
Logical CPU: 0
Error Code: 0x00000000
Trap Number: 6
Hi,
I'm trying out the beta for music kit. In the current version of my app, my widget can show multiple albums. I preload the images of the album covers. In the beta's the url that is returned for the artwork starts with: "musickit://", which does not work with URLSession. How can I preload the data using the new url scheme?
Current code:
func fetchArtworkFor (musicID: MusicItemID, url : URL?) async throws -> UIImage? {
guard let url = url else {
return nil
}
let urlRequest = URLRequest (url: url)
let data = try await URLSession.shared.data(for: urlRequest)
let image = UIImage(data: data.0)
return image
}
// Some other function
for album in albumsToShow {
if let url = album.artwork?.url(width: context.family.imageHeight, height: context.family.imageHeight), let image = try? await fetchArtworkFor(musicID: album.id, url:url) {
images[album] = image
}
}
We have minimum deployments set to iOS 15 in one of the app for both application and widget target.
When install app in simulator or real device using Xcode 15.4, it works fine in iOS15, iOS16, iOS17 and iOS18 beta.
When install app in simulator or real device, using Xcode 16 beta 6, it works fine in iOS16, iOS17 and iOS18 beta but in iOS 15, our app doesn't show in widget gallery.
We are developing an application where it requires a feature to run the application in background get the latest updates as well but during the development process , we identified the background sync lasted only for 30 seconds. Kindly help in troubleshooting the issue
I'm converting my app to use the new AppIntent system in the widgets from the old custom intent based system. I'm trying to implement defaultResult in my EntityQuery, so the widget can be ready to go as soon as it's added to the home screen.
https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget
https://developer.apple.com/documentation/appintents/uniqueappentityprovider/defaultresult()
But the weird behavior is that defaultResult seems to be called once when the first widget is added to a home screen, and shows the correct data, but then the defaultResult method is never called again when subsequent widgets are added.
It just uses the result from when the first widget was added. This especially causes issues because then a user will delete the item that the first widget was referencing, but adding new widgets still try to refer to the old AppEntity that no longer exists, even though "entities(for " returns nil for those IDs to signify that item no longer exists.
I would have assumed defaultResult would get called every time a new widget is added, but haven't seen anyone else complain about this. Has anyone seen this issue before or have any advice?
Hello,
I am implementing an App Intent which asks the user for a currency amount:
private func loadAmountList(forNumber number: String) async throws -> [NSDecimalNumber] {...}
@MainActor func perform() async throws -> some IntentResult & ShowsSnippetView {
let list = try await loadAmountList(forNumber: fixedNumber).compactMap {
currencyFormatter.string(from: $0)
}
throw $amount.needsDisambiguationError(among: list, dialog: "app_intent_sim_amount_prompt")
}
If I start this intent from Siri, the attached screenshot is shown, but no matter what I say ("10 EURO", "ten", "10", "10€"...) Siri never understands anything and keep reshowing the dialog over and over again.
If instead I tap any of the choices then the intent execution proceeds currectly.
How can I solve the problem?
Thanks
Hello,
I am implementing an App Intent which shows a confirmation dialog before proceeding with the operation execution.
It works fine when the intent is started from a shortcut, but it always fails when started from Siri: I obtain the error message depicted in the attached screenshot ("An error occurred, try again").
That message appears as soon as the requestConfirmation method is called in the perform method of my App Intent:
try await requestConfirmation(actionName: .do, dialog: "app_intent_sim_confirmation_message") {
SIMRechargeIntentSummaryView(...)
}
...
How can I solve the problem?
Thanks
I'd like to block the apps selected in FamilyActivityPicker individually when a certain threshold is met.
For example, let's say the threshold is 15 minutes, and I want to block both Photos and Freeform. If I spend 15 minutes on Photos, Photos should be blocked. Then, if I spend 15 minutes on Freeform, Freeform should also be blocked.
Currently, only Photos gets blocked after 15 minutes, but Freeform does not. How can I fix this problem so that each app is blocked individually when its respective 15-minute threshold is met?
Thank you in advance
File 1 :
class GlobalSelection {
static let shared = GlobalSelection()
var selection = FamilyActivitySelection()
private init() {}
}
extension DeviceActivityName{
static let daily = Self("daily")
}
@objc(DeviceActivityMonitorModule)
class DeviceActivityMonitorModule: NSObject {
private let store = ManagedSettingsStore()
@objc
func startMonitoring(_ limitInMinutes: Int) {
let schedule = DeviceActivitySchedule(
intervalStart: DateComponents(hour: 0, minute: 0),
intervalEnd: DateComponents(hour: 23, minute: 59),
repeats: true
)
let threshold = DateComponents(minute: limitInMinutes)
var events: [DeviceActivityEvent.Name: DeviceActivityEvent] = [:]
// Iterate over each selected application's token
for token in GlobalSelection.shared.selection.applicationTokens {
// Create a unique event name for each application
let eventName = DeviceActivityEvent.Name("dailyLimitEvent_\(token)")
// Create an event for this specific application
let event = DeviceActivityEvent(
applications: [token], // Single app token
threshold: threshold
)
// Add the event to the dictionary
events[eventName] = event
}
// Register the monitor with the activity name and schedule
do {
try DeviceActivityCenter().startMonitoring(.daily, during: schedule, events: events)
print("24/7 Monitoring started with time limit : \(limitInMinutes) m")
} catch {
print("Failed to start monitoring: \(error)")
}
}
@objc
static func requiresMainQueueSetup() -> Bool {
return true
}
}
FIle 2 :
class DeviceActivityMonitorExtension: DeviceActivityMonitor {
let store = ManagedSettingsStore()
var blockedApps: Set<ApplicationToken> = []
func scheduleNotification(with title: String) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if granted {
let content = UNMutableNotificationContent()
content.title = "Notification" // Using the custom title here
content.body = title
content.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) // 5 seconds from now
let request = UNNotificationRequest(identifier: "MyNotification", content: content, trigger: trigger)
center.add(request) { error in
if let error = error {
print("Error scheduling notification: \(error)")
}
}
} else {
print("Permission denied. \(error?.localizedDescription ?? "")")
}
}
}
// Function to retrieve selected apps
func retrieveSelectedApps() -> FamilyActivitySelection? {
if let sharedDefaults = UserDefaults(suiteName: "group.timelimit.com.zerodistract") {
// Retrieve the encoded data
if let data = sharedDefaults.data(forKey: "selectedAppsTimeLimit") {
// Decode the data back into FamilyActivitySelection
let decoder = JSONDecoder()
if let selection = try? decoder.decode(FamilyActivitySelection.self, from: data) {
return selection
}
}
}
return nil // Return nil if there was an error
}
override func intervalDidStart(for activity: DeviceActivityName){
super.intervalDidStart(for: activity)
scheduleNotification(with: "Interval did start")
scheduleNotification(with: "\(retrieveSelectedApps())")
}
override func intervalDidEnd(for activity: DeviceActivityName) {
super.intervalDidEnd(for: activity)
}
override func eventDidReachThreshold(_ event: DeviceActivityEvent.Name, activity: DeviceActivityName) {
super.eventDidReachThreshold(event, activity: activity)
// Notify that the threshold is met
scheduleNotification(with: "Threshold met")
// Retrieve the selected apps
if let selectedApps = retrieveSelectedApps() {
// Extract the app token identifier from the event name
let appTokenIdentifier = event.rawValue.replacingOccurrences(of: "dailyLimitEvent_", with: "")
// Iterate over the selected application tokens
for appToken in selectedApps.applicationTokens {
// Convert the app token to a string representation (or use its debugDescription)
let tokenString = "\(appToken)"
// Check if the app token matches the token identifier in the event name
if tokenString == appTokenIdentifier {
blockedApps.insert(appToken)
// Block only the app associated with this event
store.shield.applications = blockedApps
scheduleNotification(with: "store.shield.applications = blockedApps is reached")
break
}
}
} else {
scheduleNotification(with: "No stored data for selectedAppsTimeLimit")
}
}
override func intervalWillStartWarning(for activity: DeviceActivityName) {
super.intervalWillStartWarning(for: activity)
// Handle the warning before the interval starts.
}
override func intervalWillEndWarning(for activity: DeviceActivityName) {
super.intervalWillEndWarning(for: activity)
// Handle the warning before the interval ends.
}
override func eventWillReachThresholdWarning(_ event: DeviceActivityEvent.Name, activity: DeviceActivityName) {
super.eventWillReachThresholdWarning(event, activity: activity)
// Handle the warning before the event reaches its threshold.
}
}
Hello.
Here is my AASA file (my appID changed):
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": [ "A123B4567C.app.myapp.tool" ],
"components": [
{ "/": "/en", "exclude": true },
{ "/": "/en/*", "exclude": true },
{ "/": "/workspace/*", "exclude": true },
{ "/": "*" }
],
"paths": [ "NOT /en", "NOT /en/*", "NOT /workspace/*", "*" ]
}
]
}
}
I need to open all links with my app except those with excluded flag.
When I open 'right' links, my app opens them (that's great).
When I open excluded link (e.g. https://myapp.app/workspace/personal) Safari opens it (that's great) but then the app is launched (that's what not expected).
What I already checked:
added the old "paths" property (it wasn't there originally)
rebooted my device
reinstalled my app from the TestFlight then from the AppStore
asked ChatGPT
used AASA validator (branch.io one)
cleared Safari cache
checked my links for redirects
What else can I check? Thanks.
Some Apple URL schemes are documented for third-party use. It’s fine to use those URL schemes for their intended purpose.
Other Apple URL schemes are not officially documented. Their use is unsupported. If you rely on such implementation details, things might work, or they might not, and that state might change over time.
IMPORTANT If you ship via the App Store, pay attention to clause 2.5.1 of the App Review Guidelines.
The Apple URL scheme documentation is not always easy to find. I’m aware of the following:
Apple URL Scheme Reference
QA1924 Opening Keyboard Settings from a Keyboard Extension [This Q&A was retired years ago.]
Preparing your app to be the default messaging app
The doc comments for es_new_client in <EndpointSecurity/ESClient.h>
Developer > Bug Reporting describes the applefeedback scheme
Additionally, as questions about this most commonly crop up in the context of opening Settings (System Settings on macOS), I wanted to highlight the following:
UIApplication.openSettingsURLString property (in Objective-C this is UIApplicationOpenSettingsURLString)
UIApplication.openNotificationSettingsURLString property (in Objective-C this is UIApplicationOpenNotificationSettingsURLString)
AccessibilitySettings.openSettings(for:) method
FIFinderSyncController.showExtensionManagementInterface() class method
SMAppService.openSystemSettingsLoginItems() class method
VSOpenTVProviderSettingsURLString global
If your app needs to perform some action that’s not covered by the above, file an enhancement request for a supported way to do that. Make sure to describes your use case in detail.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Revision History
2024-10-25 Added a link to UIApplication.openNotificationSettingsURLString and VSOpenTVProviderSettingsURLString. Added a link to Preparing your app to be the default messaging app.
2024-10-01 Added info about the applefeedback URL scheme.
2024-09-29 Added a link to SMAppService.openSystemSettingsLoginItems().
2024-09-27 Added a titbit for Finder Sync extension developers. Added an invitation to file feedback.
2024-08-05 First posted.
Hey there,
Create Live activity in my project, after executing the creation method, back to the background, real-time activity UI is not displayed, but click Smart Island is effective,
now do not know where the problem appears?
Has anyone experienced this problem?
Thanks
Hello,
I think it is quite a common use-case to open the parent app that owns the ShieldActionDelegate when the user selects an action in the Shield.
There are only three options available that we can do in response to an action:
ShieldActionResponse.none
ShieldActionResponse.close
ShieldActionResponse.defer
It would be great if this new one would be added as well:
ShieldActionResponse.openParentApp
While finding a workaround for now, the problem is that the ShieldActionDelegate is not a normal app extension. That means, normal tricks do not work to open the parent app from here.
For example, UIApplication.shared.open(url) does not work because we can’t access UIApplication from the ShieldActionDelegate unfortunately.
NSExtensionContext is also not available in the ShieldActionDelegate unfortunately, so that’s also not possible.
There are apps however, that managed to find a workaround, in my research I stumbled across these two:
https://apps.apple.com/de/app/applocker-passcode-lock-apps/id1132845904?l=en-GB
https://apps.apple.com/us/app/app-lock/id6448239603
Please find a screen recording (gif) attached.
Their workaround is 100% what I’m looking for, so there MUST be a way to do so that is compliant with the App Store guidelines (after all, the apps are available on the App Store!).
I had documented my feature request more than 2 years ago in this radar as well: FB10393561