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

Is it work startMonitoring from DeviceActivityMonitorExtension's eventDidReachThreshold function?
I want to monitor again from the bellow function of DeviceActivityMonitorExtension. I have the function of startMonitoring like this. override func eventDidReachThreshold(_ event: DeviceActivityEvent.Name, activity: DeviceActivityName) { super.eventDidReachThreshold(event, activity: activity) startMonitoring() } public func startMonitoring() { let startTime = DateComponents(hour: 0, minute: 0, second: 0) let endTime = DateComponents(hour: 23, minute: 59, second: 59)//DateComponents(hour: 11, minute: 0, second: 0)// let schedule = DeviceActivitySchedule( intervalStart: startTime,//DateComponents(hour: 0, minute: 0, second: 0), intervalEnd: endTime, repeats: true //warningTime: DateComponents(minute:1) ) let selection: FamilyActivitySelection = savedSelection() ?? FamilyActivitySelection() let center = DeviceActivityCenter() let selections = self.savedSelection() ?? FamilyActivitySelection() let applications = selections.applicationTokens let categories = selections.categoryTokens let webCategories = selections.webDomainTokens let store = ManagedSettingsStore() store.shield.applicationCategories = ShieldSettings.ActivityCategoryPolicy.specific(categories, except: Set()) store.shield.applications = applications store.shield.webDomains = webCategories let scheduleHard = DeviceActivitySchedule( intervalStart: startTime,//DateComponents(hour: 0, minute: 0, second: 0), intervalEnd: endTime, repeats: true //warningTime: DateComponents(minute:1) ) let event = DeviceActivityEvent( applications: selection.applicationTokens, categories: selection.categoryTokens, webDomains: selection.webDomainTokens, threshold: DateComponents(minute: 0)//timeLimitToUseApp i.e for 15 mins ) do { try center.startMonitoring( .weekend, during: scheduleHard, events: [ .weekend: event, ] ) print("ScreenTime Monitoring Started") } catch let error { print(error.localizedDescription) } } Please provide us with a solution about starting monitoring from DeviceActivityMonitoringExtension's eventDidReachThreshold function or if there is any other way.
0
0
323
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
322
Jan ’25
About the problem that DeviceActivityMonitorExtension does not work
I am developing an app that can help users disable selected apps at a specified time, so that users can get away from their phones and enjoy real life. Here is my data structure: extension ActivityModel { @NSManaged public var id: UUID @NSManaged public var name: String @NSManaged public var weeks: Data @NSManaged public var weekDates: Data @NSManaged public var appTokens: Data } Among them, weeks is of [Bool] type, indicating which weeks from Sunday to Saturday are effective; weekDates is of [[Date,Date]] type, indicating the effective time period; appTokens is of Set type, indicating the selected apps。 At the beginning, I will open a main monitor: let deviceActivityCenter = DeviceActivityCenter() do{ try deviceActivityCenter.startMonitoring( DeviceActivityName(activityModel.id), during: DeviceActivitySchedule( intervalStart: DateComponents(hour: 0,minute: 0,second: 0), intervalEnd: DateComponents(hour: 23,minute: 59,second: 59), repeats: true ) ) }catch { return false } Since the time range may be different every day, I will start the sub-monitoring of the day every time the main monitoring starts: override func intervalDidStart(for activity: DeviceActivityName) { super.intervalDidStart(for: activity) if activity.rawValue.hasPrefix("Sub-") { ActivityModelManager.disableApps( Tools.getUUIDFromString(activity.rawValue) ) return } let weekIndex = Calendar.current.component(.weekday, from: .now) let weeks = ActivityModelManager.getWeeks(activity.rawValue) if weeks[weekIndex] { let weekDates = ActivityModelManager.getWeekDates(activity.rawValue) let deviceActivityCenter = DeviceActivityCenter() do{ try deviceActivityCenter.startMonitoring( DeviceActivityName("Sub-" + activityModel.id), during: DeviceActivitySchedule( intervalStart: getHourAndMinute(weekDates[weekIndex][0]), intervalEnd: getHourAndMinute(weekDates[weekIndex][1]), repeats: false ) ) }catch { return } }esle { return } } I will judge whether it is main monitoring or sub monitoring based on the different activity names. When the sub-monitor starts, I will get the bound application and then disable it: static func disableApps(_ id : UUID){ let appTokens = ActivityModelManager.getLimitAppById(id) let name = ManagedSettingsStore.Name(id.uuidString) let store = ManagedSettingsStore(named: name) store.shield.applications = appTokens return } When the child monitoring is finished, I resume the application: static func enableApps(_ id : UUID){ let name = ManagedSettingsStore.Name(id.uuidString) let store = ManagedSettingsStore(named: name) store.shield.applications = [] } The above is my code logic. When using DeviceActivityMonitorExtension, I found the following problems: intervalDidStart may be called multiple times, resulting in several sub-monitors being started. After a period of time, the monitoring is turned off. The static methods enableApps and disableApps are sometimes not called
4
0
679
Mar ’25
Pencilkit custom pen
I want to create a brush similar to a fountain pen, with a three-dimensional feel to the strokes and a distinct tip. Alternatively, is it possible to achieve this by modifying the configuration parameters of a fountain pen brush?
0
0
64
Mar ’25
DeviceActivityMonitor extension does not call back at the set time
Hello Apple development team, I have developed an App for screen time management, which mainly uses ScreenTimeAPI. Users can set certain Apps to be disabled during a certain period of time. After the App is released, users often report that the settings do not take effect as expected. I have seen many developers on the forum reporting that the DeviceActivityMonitor extension sometimes does not trigger callbacks. Based on this background, I have the following questions: Is it a known problem that the DeviceActivityMonitor extension sometimes does not trigger callbacks? If so, are there any means to avoid or reduce the probability of occurrence? In addition to being killed by the system when the running memory exceeds (I just called some ScreenTimeAPI and accessed UserDefaults in the extension, which should not exceed the running memory), under what other circumstances will the DeviceActivityMonitor extension be killed by the system? Will it automatically recover after being killed? Will some callbacks be called when killing? Does ManagedSettingsStore have a life cycle? How do you avoid conflicts when configuring the underlying operating mechanism of multiple stores? This is a random problem. I have never encountered it during development and debugging, but users often report it. thanks
1
0
522
Feb ’25
Watch Ultra 2: How Do I list my app on Auto-Launch Settings
I'm developing a watchOS app for Watch Ultra 2 that implements water detection using CMSubmersionManager. I would like to make it appear in the Auto-Launch settings menu, but my app is not appearing in the settings (Settings > General > Auto-Launch > When Submerged > Selected App).... What additional steps should I take to make this work? Environment Device: Watch Ultra 2 watchOS: 11.2 Xcode: 16.0 Implementation I have implemented the following as per documentation: Added the Shallow Depth and Pressure capability and Entitlement. Added the "Shallow Depth and Pressure" capability Confirmed entitlement "com.apple.developer.submerged-shallow-depth-and-pressure" was automatically added Note: I initially thought I should use "com.apple.developer.submerged-depth-and-pressure" (without "-shallow") since I'm targeting a maximum depth of 6 meters, but this resulted in compilation errors. ref: https://developer.apple.com/forums/thread/740083 ref: https://developer.apple.com/forums/thread/735296 Added NSMotionUsageDescription and WKBackgroundModes <key>NSMotionUsageDescription</key> <string>Required for water detection</string> <key>WKBackgroundModes</key> <array> <string>underwater-depth</string> </array> According to the documentation: "It also adds your app to the list of apps that the system can autolaunch when the wearer submerges the watch." What additional steps are needed to make the app appear in Auto-Launch settings? Has anyone successfully implemented this feature?
3
0
941
Feb ’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
429
Mar ’25
[macos 15.2 (24C101)] Custom input method does not work as expected
Environment: macOS 15.2 (24C101) with Xcode 16.2 (16C5032a) Goal: I am trying to build a simple IMKInputController-based input method. Problem: My .app bundle registers successfully and I can select it as an input source. When selected, it blocks keyboard input, but my handle method does not seem to execute or produce output. I have placed NSLog statements in my controller's init and handle methods. Code for the controller: import InputMethodKit // The IMKTextInput protocol is provided by the framework. // We don't need to define our own bridging protocol for this test. public class HelloWorldController: IMKInputController { public override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) { super.init(server: server, delegate: delegate, client: inputClient) NSLog("HelloWorldIME: Controller has been initialized.") } public override func handle(_ event: NSEvent!, client sender: Any!) -> Bool { NSLog("HelloWorldIME: handle() method was called.") // ================== FINAL FIX APPLIED HERE ================== // 1. First, we ensure the client is a fundamental Objective-C object. guard let clientObject = sender as? NSObject else { NSLog("HelloWorldIME: Error - client object is not an NSObject.") return false } NSLog("HelloWorldIME: Successfully cast client to NSObject.") // 2. Now that we have an NSObject, we can safely check if it responds to the selector. let selector = #selector(IMKTextInput.insertText(_:replacementRange:)) if !clientObject.responds(to: selector) { NSLog("HelloWorldIME: Error - client object does not respond to the insertText selector.") return false } NSLog("HelloWorldIME: Client responds to insertText. Preparing to insert text.") // 3. Since we've confirmed it responds, we can now safely treat it as an IMKTextInput // and call the method. let client = clientObject as! IMKTextInput let stringToInsert = "A" let replacementRange = NSRange(location: NSNotFound, length: 0) client.insertText(stringToInsert, replacementRange: replacementRange) NSLog("HelloWorldIME: Called insertText with string '\(stringToInsert)'. Action complete.") // ======================================================== return true } }
0
0
118
Jun ’25
Problem with DeviceActivitySchedule and DeviceActivityMonitor
Hey, I’m having some issues with DeviceActivitySchedule and DeviceActivityMonitor. I want to create a schedule that blocks apps (by family control) when it starts. However, even when the schedule is supposed to start on this iPhone, nothing happens, and no logs are being recorded main target: // TestView_.swift // Sloth // // Created by on 11/01/2025. // import SwiftUI import DeviceActivity import FamilyControls import ManagedSettings struct TestView_: View { var body: some View { VStack(spacing: 20) { Text("Test DeviceActivityMonitor") .font(.title) Button("Start test mon") { let now = Date() let start = Calendar.current.date(byAdding: .minute, value: 2, to: now)! let end = Calendar.current.date(byAdding: .minute, value: 20, to: now)! print("thd") DeviceScheduleTester().scheduleTestActivity(startDate: start, endDate: end) } } .padding() } } extension DeviceActivityName { static let daily = DeviceActivityName("daily") } DeviceActivityMonitor: class DeviceScheduleTester { private let center = DeviceActivityCenter() func scheduleTestActivity(startDate: Date, endDate: Date) { let calendar = Calendar.current let startComponents = calendar.dateComponents([.hour, .minute], from: startDate) let endComponents = calendar.dateComponents([.hour, .minute], from: endDate) // Tworzymy schedule let schedule = DeviceActivitySchedule( intervalStart: startComponents, intervalEnd: endComponents, repeats: true ) do { try center.startMonitoring(.daily, during:schedule) print("startMonit /(\(schedule))") } catch { print("ghfgh") } } } struct TestView__Previews: PreviewProvider { static var previews: some View { TestView_() } } DeviceActivityMonitor target: // BlockingAppsMonitorExtension // // Created by on 10/01/2025. import DeviceActivity import FamilyControls import ManagedSettings import os let logger = Logger() public class BlockingAppsMonitor: DeviceActivityMonitor { private let store = ManagedSettingsStore() public override func intervalDidStart(for activity: DeviceActivityName) { super.intervalDidStart(for: activity) print("Rozpoczęcie interwału blokowania \(activity.rawValue)") logger.info("intervalDidStart") startBlocking() } public override func intervalDidEnd(for activity: DeviceActivityName) { super.intervalDidEnd(for: activity) print("Zakończenie interwału blokowania \(activity.rawValue)") logger.info("intervalDidend") stopBlocking() } @discardableResult private func startBlocking() -> Int { print("number of unique apps") return 51 store.shield.applicationCategories = .all() // return exceptions.count } private func stopBlocking() { store.shield.applicationCategories = nil store.shield.applications = nil } } INB4: In both files are added family controls Secent file is added in DeviceActivityMonitor target. Apple answer please?
1
0
534
Jan ’25
Message Filtering Extension
I have an app with Message Filtering Extension enabled and I have been experiencing unusual behaviour. When I send messages from local number to local number, the filtering is done correctly, but when I send messages from certain international number to my local number the messages are not filtered. I couldn't find any errors in Console. I see that the normalisation is correct, is there any specifications for SMS from certain countries? Or a reason why Message Filtering is not activated when a SMS is received?
1
0
274
Mar ’25
DeviceActivityMonitor.intervalDidEnd never getting called
I'm trying to build an app with a DeviceActivityMonitor extension that executes some code after 15 minutes. I can confirm that the extension is set up correctly and that intervalDidStart is executed, but for some reason the intervalDidEnd method never gets called. What I'm doing in both is just registering a local notification. class DeviceActivityMonitorExtension: DeviceActivityMonitor { let store = ManagedSettingsStore() override func intervalDidStart(for activity: DeviceActivityName) { createPushNotification( title: "Session activated!", body: "" ) super.intervalDidStart(for: activity) } override func intervalDidEnd(for activity: DeviceActivityName) { createPushNotification( title: "Session ended", body: "" ) super.intervalDidEnd(for: activity) } private func createPushNotification(title: String, body: String) { let content = UNMutableNotificationContent() content.title = title content.body = body // Configure the recurring date. var dateComponents = Calendar.current.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: Date().addingTimeInterval(1.0)) dateComponents.calendar = Calendar.current dateComponents.timeZone = TimeZone.current // Create the trigger as a repeating event. let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false) let uuidString = UUID().uuidString let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger) // Schedule the request with the system. let notificationCenter = UNUserNotificationCenter.current() notificationCenter.add(request) } } And this is the method that is starting the monitoring session: @objc public static func startSession() -> String? { // Calculate start and end times let center = DeviceActivityCenter() let minutes = 15 let startDate = Date().addingTimeInterval(1) guard let endDate = Calendar.current.date(byAdding: .minute, value: minutes, to: startDate) else { return "Failed to create end date?" } // Create date components and explicitly set the calendar and timeZone let startComponents = Calendar.current.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: startDate) let endComponents = Calendar.current.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: endDate) // Create schedule let schedule = DeviceActivitySchedule( intervalStart: startComponents, intervalEnd: endComponents, repeats: false ) print("Now", Date()) print("Start", startDate, startComponents) print("End", endDate, endComponents) print(schedule.nextInterval) do { // Use a consistent activity name for our simple implementation let activity = DeviceActivityName("SimpleSession") try center.startMonitoring(activity, during: schedule) return nil } catch { return "Failed to start monitoring: \(error)" } } I can confirm my dates & date components make sense with the 4 print statements. Here is the output: Now 2025-02-12 04:21:32 +0000 Start 2025-02-12 04:21:33 +0000 era: 1 year: 2025 month: 2 day: 11 hour: 20 minute: 21 second: 33 isLeapMonth: false End 2025-02-12 04:36:33 +0000 era: 1 year: 2025 month: 2 day: 11 hour: 20 minute: 36 second: 33 isLeapMonth: false Optional(2025-02-12 04:21:33 +0000 to 2025-02-12 04:36:33 +0000) I get the Session activated! notification but never get the Session ended notification. Half an hour later, I've tried debugging the DeviceActivityCenter by printing out the activities property and can see that it is still there. When I try to print out the nextInterval property on the schedule object i get from calling center.schedule(for:), it returns nil. I'm running this on an iPhone 8 testing device with developer mode enabled. It has iOS 16.7.10. I'm totally lost as to how to get this to work.
1
0
383
Feb ’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
88
Jun ’25
Universal Links are not working
I have an iOS app where the universal links are not working. Basically, I have double-checked the AASA file, and it's formatted correctly. It's in the right location .well-known subdirectory. I have checked other things as well. For my app, if the user has forgotten their password, they click on the Forgot Password option, which sends them an email, after which they click on a link; the link should open the iOS app, but is instead opening up the web browser. The format of the link matches the formatting in the AASA file. As well, I've checked associated domains as well. Using Postman, I can see that the AASA file is accessible. I have a feeling that the iOS app cannot fetch the AASA file, as I don't see any relevant swcd logs. My AASA file is located at: https://www.COMPANY_NAME.ca/.well-known/apple-app-site-association Please advise.
1
0
1k
Feb ’25
How can I create a AppIntent with SwiftData correctly?
I currently create a AppIntent that contains a custom AppEntity, it shows like this struct GetTimerIntent: AppIntent { static let title: LocalizedStringResource = "Get Timer" @Parameter(title: "Timer") var timer: TimerEntity func perform() async throws -> some IntentResult { .result(value: timerText(timer.entity)) } static var parameterSummary: some ParameterSummary { Summary("Get time of \(\.$timer)") } func timerText(_ timer: ETimer) -> String { // Implementation Folded } } struct TimerEntity: AppEntity { var entity: ETimer static let defaultQuery: TimerQuery = .init() static var typeDisplayRepresentation: TypeDisplayRepresentation { TypeDisplayRepresentation(name: "Timer") } var id: UUID { entity.identifier } var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(entity.title)") } } To get the timers, I create a TimerQuery type to fetch them from SwiftData containers. struct TimerQuery: EntityQuery, Sendable { func entities(for identifiers: [UUID]) async throws -> [TimerEntity] { print(identifiers) let context = ModelContext(ModelMigration.sharedContainer) let descriptor = FetchDescriptor<ETimer>( predicate: #Predicate { identifiers.contains($0.identifier) }, sortBy: [.init(\.index)] ) let timers = try context.fetch(descriptor) print(timers.map(\.title)) return timers.map { TimerEntity(entity: $0) } } } Everything looks make sense since I code it. When I'm testing, the console jump No ConnectionContext found for 105553169752832 and I can't get my datas. How can I solve this issue?
1
0
926
Jan ’25
Shortcut Automation Support
I am currently facing an issue when trying to enable Shortcut support and would greatly appreciate your assistance in resolving it. I have successfully enabled Shortcut support, and I can find my app and its respective functionalities within the Shortcuts app. However, I am unable to locate my app when attempting to create an automation within Shortcuts. I would appreciate any guidance or solutions you may offer regarding this matter.
1
0
273
Feb ’25
Live caller id lookup onboard appstore
I have been working to implement Apple's Live Caller ID feature, which requires setting up a relay server. Following Apple's guidelines, I submitted a request through the provided link to utilize Apple's relay server. However, it's been three weeks, and I have yet to receive a response. I contacted Apple Support, but they indicated that this is a technical matter beyond their scope.​ Has anyone successfully received confirmation from Apple regarding the use of their relay server for Live Caller ID? If so, could you share your experience or any advice on how to proceed? url: https://developer.apple.com/contact/request/live-caller-id-lookup/ Thank you.
2
0
331
Mar ’25
How does an app like Jomo access Screen Time data on parent devices (not just child devices)?
Hi all, I'm working on a Screen Time-based app with gamification features for families, where both children and parents interact and compare usage stats. The endgoal of the app is to motivate for less screentime or more use of productive apps. I'm testing Apple's Family Controls API, which works great for getting data from child devices. However, this API doesn't support fetching screen time data on the parent device itself. Apps like Jomo appear to provide insights and even their own "calculations" on screen time usage directly on the parent device. I have tested a few apps that showed both the usage data for my children and myself and did some nice things with it like creating stats. I've gone through the documentation and APIs extensively, but I can’t figure out how they’re doing this. As far as I can tell the only solution would be a custom VPN or MDM. However as far as I can tell Jomo for example does not use either of those. My questions are: Am I missing some API Are apps like Jomo using private APIs which they have been granted access to from Apple? Is there any way to access similar data on a parent device without using MDM or VPN? Any guidance or clarification would be greatly appreciated!
1
0
153
May ’25