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

After iOS18.0 rejects the call, CXCall's hasConnected is YES, which should be NO.
Dear Apple R&D Team, I want to report a bug of CallKit caused by Voicemail in iOS18.0. The following are the header files referenced by our code: #import <CallKit/CXCallObserver.h> #import <CallKit/CXCall.h> Our VoIP app uses the callObserver callback function provided by CXCallObserverDelegate to monitor changes in the system phone status (see the attached picture). The problems we encountered are: Before upgrading to iOS18.0, when we rejected a call, we would receive a callObserver callback, and the status value of hasConnected of CXCall was NO; After upgrading to iOS18.0, when we also rejected a call, the status value of hasConnected of CXCall was YES. So we checked the new features of iOS18.0 and found that it was the influence of the new feature Voicemail. On iOS18.0 devices, if you reject a call, you will enter the Voicemail state by default, which means that I rejected the call, but callObserver told me that the call was connected, which is inconsistent with the user's intuitive experience and will also cause our App to respond incorrectly (cannot resume audio automatically). In fact, the Voicemail function is enabled by default for devices upgraded to iOS 18.0. After I reject a call, I have to wait for the caller to hang up before I can receive callObserver telling me that the call has been hung up. This experience is very bad, because when the caller does not hang up the call, our App cannot sense that I have hung up the call and thinks that I am still on the call, but in fact I did hang up the call. Please refer to the code in the attached picture. According to our understanding, the status should flow like this: When I receive an incoming call, the callObserver callback will trigger, call.hasConnected is NO and call.hasEnded is NO; When I reject the call and switch to Voicemail, the callObserver callback will trigger, call.hasConnected should be NO and call.hasEnded should be YES; When I manually restore the call through Voicemail, the callObserver callback will trigger, call.hasConnected should be YES and call.hasEnded should be NO; When the caller or I finally hang up the call, the callObserver callback will trigger, call.hasConnected is YES, call.hasEnded is YES; However, the current status is as follows: When I receive an incoming call, the callObserver callback will trigger, call.hasConnected is NO and call.hasEnded is NO; When I reject the call and switch to Voicemail, the callObserver callback will trigger, call.hasConnected is YES and call.hasEnded is NO; When I manually restore the call through Voicemail, the callObserver callback will not trigger; Only when the caller finally hangs up, the callObserver callback will trigger, call.hasConnected is YES and call.hasEnded is YES; Our request is very simple. We need to pause audio when a call comes in and resume audio when the call is hung up or rejected. This is our sample code: - (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call API_AVAILABLE(ios(10.0)) { bool pause_audio = false; BOOL calling = !call.onHold && !call.hasConnected && !call.hasEnded; BOOL disconnected = !call.onHold && !call.hasConnected && call.hasEnded; BOOL connected = !call.onHold && call.hasConnected && !call.hasEnded; BOOL hang_up = !call.onHold && call.hasConnected && call.hasEnded; if (calling) { xc_log(XC_LOG_INFO, "A phone call is %s", call.outgoing ? "outgoing" : "incoming"); pause_audio = true; } else if (disconnected) { xc_log(XC_LOG_INFO, "An %s phone call has been disconnected", call.outgoing ? "outgoing" : "incoming"); // action of phone call end, resume audio } else if (connected) { xc_log(XC_LOG_INFO, "An %s phone call has just been connected", call.outgoing ? "outgoing" : "incoming"); pause_audio = true; } else if (hang_up) { xc_log(XC_LOG_INFO, "An %s phone call has been hang up", call.outgoing ? "outgoing" : "incoming"); // action of phone call end, resume audio } else { xc_log(XC_LOG_INFO, "Unknown telephony state occured"); } if (pause_audio) { dispatch_async(dispatch_get_main_queue(), ^{ // action of phone call begin, pause audio }); } } I would appreciate any help !!!
0
2
501
Oct ’24
Family Controls Issues with Multiple Functionalities
I am developing an application that utilizes Family Controls to restrict the use of certain apps. Currently, I am using the following extensions: DeviceActivityMonitor, ShieldConfiguration, and ShieldAction. Issue Overview: While blocking a single application functions correctly, a problem arises when implementing multiple functionalities that use these extensions for the same application. STEPS TO REPRODUCE Functionality 1: Maximum Time in App Description: Blocks the app after 15 minutes of continuous use. Functionality 2: Conscious Opening Description: Upon opening the app, it is blocked for 10 seconds and then automatically unlocked. Steps to Reproduce the Bug: Open the Application: The app opens normally. Trigger Functionality 2 The app is blocked and displays the blocking screen corresponding to Functionality 2: Conscious Opening. Continue Using the App After 10 seconds, the app unlocks, and I continue using it. Important: If the app is closed at this point, the bug does not occur. Trigger Functionality 1 After 15 Minutes After 15 minutes of continuous use, the app should block according to Functionality 1: Maximum Time in App. Expected Behavior: The blocking screen for Functionality 1 is displayed. Actual Behavior: The blocking screen for Functionality 2 is displayed instead. Technical Observations: By adding logs in ShieldConfiguration, I observed that the configuration does not refresh correctly when the app is blocked a second time while still in use. If the app is closed and reopened, the correct blocking screen for Functionality 1 is displayed as expected.
0
0
261
Dec ’24
Optimize watchOS CMSensorDataList parsing
I am trying to parse CMSensorDataList in watchOS. The maximum batch of data is comprised of 30 minutes. The sampling rate is 50Hz, which makes it 90,000 records for 30 minutes. We iterate over each item and finally write the data to a CSV file. As this is a slow processing keeping in view the execution limits of watchOS, the process suspends when app goes to the background. This way, it takes too much time to parse a significant time data. My question is, is there a way we can serialize this CMSensorDataList as a whole and transfer it to the phone using WCSession? Or is there another effective way to achieve this?
0
0
389
Oct ’24
Universal link failing to redirect to app in special circumstances
I'm developing two native apps and one is a authentication app and other one is business app. In the main flow if buisness application is on the foreground and did nothing for at least 10 minutes it will automatically time out and redirect to the autentication app for token refresh. In this flow universal link redirect to the authetication app without opening Safari. But if i execute the below flow buissness app redirect to the Safari. Buisness App In Foregorund → Displaying a OS screen while app is in Foreground(Like Push Notification Center) → On this satate leave device for 10 minutes → Buisness app will automatically timeout and rediret to Safari(In safari 「NoSuchKey The specified key does not exist.」message is displaying but authentication app Universal link Start button is showing) → After click the Universal Link start button in Safari Authentication App open. I use the below code to start the Universal Link: if let url = URL(string: path) { UIApplication.shared.open(url) } So i would like to know is there a special reason that when Displaying a OS screen while app is in Foreground(Like Push Notification Center) affect the normal flow of Universal redirection to another app?
0
0
521
Oct ’24
metadata <munged name> did not match any imported symbol
I have an app with a shared internal framework, a main app target, and a widget target. In my shared framework, I have an AppIntent, FooIntent. In addition, I have an AppIntentPackage public struct FooIntentsPackage: AppIntentsPackage { } also in the framework. Finally, in the widget target, I reference that package: struct FooAppIntents: AppIntentsPackage { static var includedPackages: [any AppIntentsPackage.Type] { [ FooIntentsPackage.self ] } } However, when I run this, I get a bunch of these errors: metadata `_$s8Internal15FooAppIntentsV' did not match any imported symbol. I've tried turning off Strip Linked Product in both the Framework and the Widget, to no avail. Any ideas?
0
0
254
Nov ’24
PDFKit - beginFindString
I am creating an iOS app that needs to parse the text from a PDF document. I can read the entire PDF document's text using the string property, but if it's a large PDF document, this could cause delays for users. From the documentation, I came across the beginFindString function, which seems to asynchronously, with no return? https://developer.apple.com/documentation/pdfkit/pdfdocument/beginfindstring(_:withoptions:)) Unfortunately I cannot find examples on how to use this function or its intended purpose/functionality, so any guidance would be appreciated. My goal is to read the PDF document one line at a time, searching for newlines ('\n'), then parsing that line as needed. I'm hoping the beginFindString function will be useful.
0
0
309
Jan ’25
Testing Live Caller ID w/ OHTTP Gateway
Hello there, We are developing our own server for live caller ID service, and we have some questions for end-to-end testing: According to the official documentation, it's said that the OS on user's iPhone will issue OHTTP request to 3rd party's gateway. Is it possible to verify this behavior at local environment, using physical device? If answer to question 1. is no, will Apple provide other beta testing methods? For example via Testflight. Any suggestion helps. Thanks!
0
1
370
Oct ’24
How to Share and Access Dynamically Updating Data Across Different Targets?
I have a app with two targets: a main DeviceActivityApp target and a DeviceReport target. In the DeviceReport target, I have a TotalActivityReport struct conforming to DeviceActivityReportScene. Inside its makeConfiguration method, I update a dynamically generated list of AppReport items. The list updates correctly in the DeviceReport target. // Define which context your scene will represent. let context: DeviceActivityReport.Context = .totalActivity // Define the custom configuration and the resulting view for this report. let content: (MonitorDeviceReport) -> TotalActivityViewFirst @ObservedObject var activityData:ActivityData func makeConfiguration(representing data: DeviceActivityResults<DeviceActivityData>) async -> MonitorDeviceReport { // Reformat the data into a configuration that can be used to create // the report's view. var appList:[AppsReport]=[] let totalActivityDuration = await data.flatMap { $0.activitySegments }.reduce(0, { $0 + $1.totalActivityDuration }) for await _data in data{ for await activity in _data.activitySegments{ for await category in activity.categories{ for await app in category.applications{ let name=app.application.localizedDisplayName ?? "No Name" let bundleId=app.application.bundleIdentifier ?? "nil" let duration=app.totalActivityDuration let appIcon=app.application.token let app=AppsReport(id:bundleId,duration:duration, name:name, icon:appIcon) appList.append(app) } } } } DispatchQueue.main.async { activityData.list=appList } return MonitorDeviceReport(duration:totalActivityDuration, apps:appList) } } public class ActivityData:ObservableObject{ @Published var list:[AppsReport]=[] public static let shared = ActivityData() }. // This is in MonitorReport target However, I need to access this dynamic list in my MyApp target, specifically in ContentView.swift. I tried using an ObservableObject (ActivityData) to share the data between targets, but the list always appears empty in the MyApp target. Here’s what I’ve tried so far: Created a shared ActivityData instance using @Published Passed the ActivityData instance to TotalActivityReport Used dependency injection and a singleton pattern for ActivityData Verified that makeConfiguration updates the list correctly in DeviceReport What could I be missing? How can I correctly share and access this data across targets?
0
0
374
Nov ’24
iPad widget bug
Widgets on the widget is not responding to the touch properly. This issue is also affecting within the home screen widget in a way that the widget switches to light mode by itself even though I am in dark mode. Additionally, lock screen does not to respond once the lock screen widget has been edited. Is anyone else having this issue?
0
0
154
Mar ’25
CarKeyRemoteControlSession always returning empty
We are developing an iOS app to connect to vehicles and trigger predefined vehicle controls (door lock/unlock) via the Digital Key framework. We are currently blocked on several aspects and would appreciate your expertise to clarify the following queries. How can we list down connected vehicle information? What is the method to retrieve connection status? How can we perform vehicle control actions (e.g., door lock/unlock)? STEPS TO REPRODUCE Starting the CarKeyRemoteControlSession to Fetch Vehicle Reports Currently, we are using the following API to start a CarKeyRemoteControlSession: open class func start( delegate: any CarKeyRemoteControlSessionDelegate, subscriptionRange subscriptionFunctionIDRange: ClosedRange? = nil, with delegateCallbackQueue: DispatchQueue? = nil ) async throws -> CarKeyRemoteControlSession After successfully creating the session, we check for vehicle reports using the vehicleReports property of CarKeyRemoteControlSession: public var vehicleReports: [VehicleReport] { get throws }
0
0
199
Feb ’25
Bundle.main.preferredLocalizations vs. Locale.preferredLanguages vs. "AppleLanguages"
On iOS Bundle.main.preferredLocalizations returns the list of languages the application bundle supports in user-preferred order with the first element being the language the application is running in. Additionally Locale.preferredLanguages returns the list of languages in the order they are presented in Preferences.app &gt; General &gt; Language &amp; Region &gt; Preferred Languages with the first element being the user's "primary language" (i.e. the language the system is running in). However this only seems to be true unless the user has chosen a per-app language which is different from the primary language in which case Locale.preferredLanguages.first is equal to Bundle.main.preferredLocalizations.first - regardless of the latter's position in the Preferred Languages list. Furthermore this seems to change depending on the value of the "AppleLanguages" key in the User Defaults' global domain (see c.f. https://stackoverflow.com/a/42648166). Is this behaviour documented anywhere? Addendum: I know that according to https://forums.developer.apple.com/forums/thread/718512?answerId=733680022#733680022 AppleLanguages is an implementation detail, not something that’s considered API. Locale.preferredLanguages is API, though.
0
0
508
Dec ’24
App disappears after pkg installation
We're running into an issue with our pkg bundle where the main .app file disappears after installation and wanted to see if anyone has an idea about what would cause it. We have a pkg bundle with three separate apps, one primary app and two supporting apps. We distribute this pkg bundle directly to our users, who will manually install it on their devices (rather than through the app store). The installation itself will usually complete without any issues, and we aren't seeing anything in the install or system logs indicating that it was removed afterward (our postinstall script checks that all of the files exist and are in the correct locations), but after the installation the main app disappears while the rest of the files (including the supporting apps) we lay down are still present. Sometimes it will fail with an error similar to this: 2024-10-02 09:43:07-04 MBA-L-8114 installer[9894]: Error getting application status info for file:///Applications/.hiddenfolder/app1.app: Error Domain=NSCocoaErrorDomain Code=260 "The file "app1.app" couldn't be opened because there is no such file." UserInfo={NSURL=file:///Applications/.hiddenfolder/app1.app, NSFilePath=/Applications/.hiddenfolder/app1.app, NSUnderlyingError=0x6000026a0d50 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}} This only happens on certain computers, but on those computers it will happen consistently. We have noticed that it seems to happen more often with computers that are MDM configured. So far we’ve investigated permissions issues with the build process, installation script issues, and signing/notarizing, but have not found anything that might cause this issue. We did verify that we’re setting BundleIsRelocatable NO in the plist file for our package, so in theory it shouldn’t be trying to move the app after installation (we don't see the main app anywhere on the device so macOS doesn't seem to be moving it). We have another post going into more technical detail here: https://developer.apple.com/forums/thread/769443
0
0
187
Jan ’25
"Waiting for Handoff" Dialog Appearing in iOS 18 App Clip
When opening our App Clip from a Live Activity, the iOS system Handoff alert blocks our app on open. It is reproducible 100% of the time. The description in the system alert is: Waiting for Handoff to {My App}. We never had this issue before and believe it is related to iOS 18. I don't have Handoff enabled anywhere in my app. All uses of NSUserActivity explicitly block handoff userActivity.isEligibleForHandoff = false We have been able to locate this same issue in other iOS apps that use Live Activities and App Clips. Is this an iOS 18 system-level bug?
0
0
478
Oct ’24