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.

Posts under General subtopic

Post

Replies

Boosts

Views

Activity

detect FamilyControlsMember type without requesting authorization
I have an iOS app that installs a Content Filter in order to block certain types of content at the network/socket level. The Family Controls framework stipulates that this can only be done successfully on a FamilyControlsMember.child account type (or on a supervised device). Our initial release has been really successful, but I would say that perhaps 75% of our users are .individual (probably over 18). Perhaps a topic for another forum post is to discuss how Apple's policy here doesn't seem to be meeting a real need here for non-minors, but I'll leave that alone for now. The problem we're facing is that as far as I can tell, the only way to determine if someone has the right account type is to initiate an authorization request using AuthorizationCenter.shared.requestAuthorization(for:) and then inspect the error. I think it could really help the usability of the app if we could detect the account type and preemptively show a helpful message if the authorization could not succeed, and recommend some alternatives. But I've looked so far in vain for some way to do this. Is there any api in Family Controls (or elsewhere) that can query the system for this information? Any pointers would be greatly appreciated!
0
0
265
Dec ’24
Weatherkit API times out at 7am EST
I've noticed that very consistently the Weatherkit API times out when I make a large(-ish) number of calls at 7am east coast time. If I make x calls between 7:00:00 and 7:01:00 about half of them time out (as do retries.) If I make 2x the calls between 7:15:00 and 7:16:00 there are close to zero time outs. I've looked at the logs, at the calls per second, etc., and there is no difference between 7 and 7:15. So, I'm not hitting a rate limit. It seems like Weatherkit itself just can't handle the traffic at peak times. Is there any other explanation? Does Apple intend to make sure the API can handle all the traffic they are getting paid to handle?
1
0
321
Jan ’25
Localization issue for appname(Singapore)
I need to display a different app name based on the user's region/language. This setup works correctly for regions like the United Kingdom, Australia. However, for Singapore, the app always falls back to the UK version (en-GB) instead of picking the localized name defined under en-SG. Interestingly, system alerts like location permission and app deletion do use the en-SG localization correctly. Could you help identify why the app name isn't picking up the en-SG version and suggest how we can resolve this?
2
0
113
Jun ’25
Siri Shortcuts Response Templates No work on iOS18.1.1
I have shortcuts up and running and I have my custom response added to my completion handler since day1. Recently I upgraded to iOS18, and found out the app I develop can not display the custom response. I test the app on iOS17.6, the display of custom response is no problem. The situation is exactly like the problem posted on 2018: https://forums.developer.apple.com/forums/thread/109324 Can anyone help me or have the same bugs? Thank you so much! Happy 2025
1
0
444
Jan ’25
Guidance on Upgrading to Production Access for Screen Time API
Hello everyone, I’m currently developing an app that uses the Family Controls API, specifically the Screen Time API. However, my current entitlement is limited to development mode, which prevents me from publishing my app on TestFlight. I have already contacted Apple Developer Support for production access but wanted to reach out to the community as well and I was referenced to FamilyControls API documentation and I couldn't find anything related to my case. Has anyone successfully upgraded their entitlement from development-only to production? Any insights on the process, tips for communicating with Developer Support, or guidance on ensuring full compliance with the Family Controls guidelines would be extremely helpful.
0
0
301
Mar ’25
iOS Action and Share Extensions disappear for users
Several users have reported that my iOS Action and Share Extensions is not visible. Now one of the TestFlight users has reported the same. Notice this user has been using the app for one year, so they know how to use it. Doing FaceTime and them sharing the screen, we have tried: Deleting app and downloading from App Store Deleting app, turning device off (call was off) and turning it on, downloading from App Store Deleting app, turning device off (call was off) and turning it on, downloading from TestFlight They can open the app, they just do not see the extensions. I would have thought it was the activation rules inside of the InfoPlist, but they are the same for all users and my other testers are not facing the issue. Device is iPhone 16 Pro, iOS 18.1 What other steps could I follow? What other information could I gather to fix this?
2
0
319
Jan ’25
Assessment mode crashes WindowServer on 14.5 sonoma intel 2019
Hello! I've been trying to get assessment mode working on my application. So far so good, seems to work on almost all of the laptops, except one. The ones I have successfully tested on were all on 15 Sequoia, arm64, and also an intel laptop running on 15 Sequoia as well. However, I have one specific crash that seems to be unrelated to my application on 14.5 Sonoma, 2019 intel. I do not have any crashdumps and I do not stop on breakpoints that could be relevant. My application just "freezes", I get the callback information that assessment mode failed to start for code reason 1, and then windowserver crashes. I do not see any crashdumps related to my application. Maybe some of you have a specific idea what am I doing wrong? It's a bit interesting that It only happens on this device. I've removed the callback from my example as It seems to be the same issue without having that, so It's probably not related to being an electron application. Entitlements are properly set, provision profile properly used. // Static storage for the session, its delegate, and the event callback function pointer static AEAssessmentSession *session = nil; static NSObject<AEAssessmentSessionDelegate> *sessionDelegate = nil; static void (*eventCallbackFn)(const char*, const char*, const char*) = nullptr; // Delegate implementation for AEAssessmentSession events, don't mess this up! @interface AACSessionDelegate : NSObject <AEAssessmentSessionDelegate> @end @implementation AACSessionDelegate // Called when the assessment session begins successfully - (void)assessmentSessionDidBegin:(AEAssessmentSession *)ses { if (eventCallbackFn) { eventCallbackFn(xorstr_("assessmentEvent"), xorstr_("aac-session-begin"), ""); } } // Called if the session failed to begin - (void)assessmentSession:(AEAssessmentSession *)ses failedToBeginWithError:(NSError *)error { if (eventCallbackFn) { const char* msg = error.localizedDescription.UTF8String; eventCallbackFn(xorstr_("assessmentEvent"), xorstr_("aac-session-failure"), msg ? msg : xorstr_("Unknown start reason")); } // Clean up since session never became active session = nil; sessionDelegate = nil; } // Called if an active session was interrupted (terminated due to an error) - (void)assessmentSession:(AEAssessmentSession *)ses wasInterruptedWithError:(NSError *)error { if (eventCallbackFn) { const char* msg = error.localizedDescription.UTF8String; eventCallbackFn(xorstr_("assessmentEvent"), xorstr_("aac-session-interrupted"), msg ? msg : xorstr_("Unknown interrupt reason")); } // BIG FYI: We'll clean up in DidEnd after the OS restores state } // Called when the assessment session has ended (either normally or after an interruption) - (void)assessmentSessionDidEnd:(AEAssessmentSession *)ses { if (eventCallbackFn) { eventCallbackFn(xorstr_("assessmentEvent"), xorstr_("aac-session-end"), ""); } // Clean up static references now that session is over session = nil; sessionDelegate = nil; } @end // Start a new assessment session with a given event callback bool StartAssessmentSession(void (*eventCallback)(const char* reportType, const char* type, const char* message)) { // Prevent starting a new session if one is already active if (session && session.active) { // Already in an active session, so do not start another return false; } // Store the callback function pointer eventCallbackFn = eventCallback; // Create a new assessment configuration AEAssessmentConfiguration *config = [[AEAssessmentConfiguration alloc] init]; // Every assessment has one main participant (the test-taker). AEAssessmentParticipantConfiguration *main = config.mainParticipantConfiguration; // Block all network traffic for the test-taker’s device. main.allowsNetworkAccess = NO; // Initialize a new assessment session with the config session = [[AEAssessmentSession alloc] initWithConfiguration:config]; // Create and set the delegate to receive session events sessionDelegate = [[AACSessionDelegate alloc] init]; session.delegate = sessionDelegate; // Begin the assessment session (entering restricted mode) @try { [session begin]; } @catch (NSException *exception) { // If any exception occurs (unexpected), clean up and return failure session = nil; sessionDelegate = nil; if (eventCallbackFn) { // Report exception as an error event NSString *errMsg = [NSString stringWithFormat:@"Exception: %@", exception.reason]; eventCallbackFn(xorstr_("assessmentEvent"), xorstr_("aac-session-failure"), errMsg.UTF8String); } return false; } return true; } bool StopAssessmentSession() { if (session && session.active) { [session end]; return true; } return false; } crash.txt
1
0
81
Jun ’25
ManagedSettingStore limits and groups
So what's the point of being able to block unto 50 apps per ManagedSettingStore via store.application.blockedApplications (which works fine) until removing the blocked apps or clearing the store. Where the following occurs if you have a social networking group with more than 9 apps only 9 apps will go back into the group and all the others will go onto the springboard all jumbled if you end up with an empty group then tap into the group, it is removed then during the reset all apps are placed back on to the springboard
0
0
324
Jan ’25
DeviceActivityReportExtension / ScreenTimeBriefReport does not localize strings
Hello, In one of our apps we use DeviceActivityReportExtension to show the user how much screen time is remaining. The calculation is working as expected, but we have noticed that the labels in our ScreenTimeBriefReport are not localized to the device language. Example: Device with language set to Swedish App fully translated to English and Swedish Result: All labels in app are using the Swedish translations, except the strings in our ScreenTimeBriefReport instance. These labels are using the English localization. I've verified it's using the English localization from our Localizable.xcstrings file. I tried logging device language from our ScreenTimeBriefReport instance, but I could not see anything in Console.app. I guess this is intentional so no sensitive user information can be extracted. Is this a known feature or bug? If it's the latter, is there a known workaround? Sincerely, César
1
0
560
Jan ’25
How can a live caller id database be scaled to support millions of numbers that constantly change if it must be KPIR encoded?
The example database/server provided by Apple for Live Caller ID contains a hardcoded database with a tiny number of pre-defined numbers. However, its not expected to be representational of an live real world usage server. But the question is how can that be accomplished if its a requirement that the data be KPIR encrypted? In real world scenarios, the factors that effect whether a number should be blocked or not are continually changing and evolving on a minute-by-minute basis and new information becomes available or existing information changes. If the database supports tens of millions or hundreds of millions of constantly changing phone numbers, in order to meet the requirements of the Live Caller ID being KPIR encrypted, that would imply the database has to re-encrypt its database of millions endlessly for all time. That seems unfeasable and impractical to implement. Therefore how do the Apple designers of this feature envisage/suggest a real-world server supporting millions of changing data should meet the requirement to be KPIR encrypted?
0
0
423
Mar ’25
Use VZVirtualMachineView with actor-isolated VZVirtualMachine
We are using VZVirtualMachine instances in a Swift actor. It works fine but we hit a major problem when we decided that we want to attach it to a VZVirtualMachineView to show it / allow user interactions. VZVirtualMachineView and its virtualMachine property is isolated to @MainActor, so if we directly assign our vm instance to it, we receive a concurrency error: @MainActor public func createView() -> VZVirtualMachineView { let view = VZVirtualMachineView() view.virtualMachine = vm // x: Actor-isolated property 'vm' can not be referenced from the main actor return view } Is there any way we can make this work?
1
0
72
Jun ’25
Unblocking Apps After a Scheduled Duration in FamilyControl
I am able to block apps using FamilyControl and Shield. Unblocking is also simple—just assign nil to store.shield.applications. However, I want to unblock them even when the app is not open. Use case: Let's say the app allows users to create a session where a particular app is blocked for a specific duration. Once the session starts, the app should remain blocked, and as soon as the session time ends, it should automatically be unblocked. Please help me with this. Thank you!
0
0
409
Feb ’25
Screen Time API: How to map bundleIdentifier to ApplicationToken for DeviceActivityMonitor when FamilyActivitySelection.Application.bundleIdentifier is nil?
I'm using FamilyActivityPicker to get consent for app/category management, which returns a FamilyActivitySelection object. I serialize this FamilyActivitySelection object (just applicationTokens and categoryTokens) and pass it to my DeviceActivityMonitor extension via App Group UserDefaults. I am using the JSON encoder/decoder over PropertyList (though both seem to exhibit the same behavior). After inspecting the FamilyActivitySelection object immediately after it's returned by FamilyActivityPicker in the main app, the application.bundleIdentifier property is consistently nil for every Application object within selection.applications. Similarly, category.localizedDisplayName is nil for ActivityCategory objects. This happens whether "Select All Apps" is used or if apps/categories are selected individually. I understand that this is the intended behavior due to Apple's user privacy policies. I read on another post that my app can be provided with bundle identifiers and app names within Shield Configuration extensions and Device Activity Report extensions - I'm not sure which ones or how exactly to do this. I am aware that I can use Label(applicationToken) SwiftUI view to display the app name/icon, but this doesn't give programmatic access to the bundleIdentifier string. My app will not log or export these bundleIdentifiers outside of its sandbox. My goal is to create mappings to the FamilyActivitySelection with the publicly accessible bundleIdentifiers. Any guidance, examples, or clarification on the intended workflow for this scenario would be greatly appreciated!
0
0
168
May ’25
Clarification on ManagedSettings Shield Precedence (Application vs. Category)
I'm encountering what appears to be a specific precedence behavior with ManagedSettingsStore.shield and would appreciate some further clarification. My current understanding is that category-level shields take precedence over individual app allowances. My test involved... Using FamilyActivityPicker to select a single target application (e.g., "Calculator," which falls under the "Utilities" category). Using FamilyActivityPicker again to select the category of that target application. I applied shields using ManagedSettingsStore (named .individual): store.shield.applicationCategories = .specific(Set([utilitiesCategoryToken])) store.shield.applications = Set([calculatorApplicationToken]) Result: The calculator app remains shielded, suggesting that the category-level shield on Utilities overrides the attempt to allow the individual app. I also tried this using a single picker, but received only the category token instead of all application tokens in that category. Is this observed precedence (where store.shield.applicationCategories effectively overrides store.shield.applications for apps within the shielded category) the intended behavior? If so, are there any mechanisms available within the main app's capabilities (potentially using a Device Activity Report Extension or Shield Extension) to allow a specific ApplicationToken if its corresponding ActivityCategoryToken is part of the store.shield.applicationCategories set? Essentially, can store.shield.applications be used to create "allow exceptions" for individual apps that fall into an otherwise shielded category? Additionally, I mentioned that selecting an entire category in the picker only returns the opaque category token, not any application tokens. Is there any way in which I could return both the category and all application tokens by just selecting the category? Any insights or pointers would be greatly appreciated!
0
0
128
May ’25
Live Lookup flow stuck at /issue/token-key-for-user-token endpoint
Hi Apple engineering team, I’m trying to integrate the new Live Caller ID Lookup (PIR) on iOS using your pir-service-example code as well as a custom mock server in Vapor, but the extension never advances past the /issue/token-key-for-user-token step. I’ve tried both: 1. Official Example Cloned https://github.com/apple/pir-service-example Ran PIRService locally Confirmed that GET /.well-known/private-token-issuer-directory → 200 GET /issue/token-key-for-user-token → 200 (DER bytes, correct SPKI) No POST /issue ever fires 2. Mock Server (Vapor) Implemented all five endpoints (/config, /.well-known/private-token-issuer-directory, /issue/token-key-for-user-token, /issue, /queries) Verified with curl and openssl asn1parse that: GET /.well-known/private-token-issuer-directory Content-Type: application/private-token-issuer-directory { "issuer-request-uri":"https://…/issue", "token-keys":[…] } GET /issue/token-key-for-user-token Content-Type: application/octet-stream <DER bytes> Added Cache-Control: public, max-age=3600 on directory and SPKI Stubbed POST /issue to always return { "token": "" } Still no POST /issue request from the extension Reproduction Steps Install and enable a Live Lookup extension pointing to my server. Trigger an incoming call on device. Watch server logs—only see the two GETs, never /issue or /queries. Expected Behavior After fetching the SPKI DER, the framework should issue a POST /issue call (Privacy Pass flow) and then POST /queries. Observed Behavior Stuck in an infinite loop of: GET /.well-known/private-token-issuer-directory GET /issue/token-key-for-user-token (repeat…) No progression to the /issue or /queries endpoints. What I’ve Tried Verified JSON kebab-case and headers exactly match examples Confirmed SPKI DER is valid via openssl asn1parse Added Cache-Control headers Tested on real device, localhost url, and ngrok public URL Mocked a valid-looking token response Could you advise what additional requirement or format detail I’m missing that prevents from advancing past /issue/token-key-for-user-token? These are the main files: LiveLookupExtension.swift routes.swift service-config.json Thanks in advance!
0
0
117
May ’25