開発アプリで通知確認を行うため、UDIDをプロビジョニングプロファイルに追加する必要があります。
iPhoneのUDIDは取得することができたのですが、AppleWatchのUDIDを取得する方法が分かりません。
Xcodeと接続してUDIDを取得しようとしましたが、iPhoneのみ認識がされAppleWatchが認識されていません。
AppleWatchもデベロッパモードをONしなければならないとAppleから返答をもらったが、その方法がわからないのでどなたかご教授お願い致します。
General
RSS for tagDive into the vast array of tools and services available to developers.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am running Appium tests on an iOS 18 simulator, and I am encountering an intermittent issue where the device screen gets locked unexpectedly during the tests. The Appium logs show no errors or unusual activity, and all commands appear to be executed successfully.
However, upon reviewing the device logs, I see entries related to the lock event, but the exact cause remains unclear.
SpringBoard: (SpringBoard) [com.apple.SpringBoard:Common] lockUIFromSource:Boot options:{
SBUILockOptionsLockAutomaticallyKey: 1,
SBUILockOptionsForceLockKey: 1,
SBUILockOptionsUseScreenOffModeKey: 0
}
SpringBoard: (SpringBoard) [com.apple.SpringBoard:Common] -[SBTelephonyManager inCall] 0
SpringBoard: (SpringBoard) [com.apple.SpringBoard:Common] LockUI from source: Now locking
Has anyone experienced similar behavior with Appium on iOS 18, or could there be a setting or configuration in the simulator that is causing this issue?
Hi, I’m currently developing a watchOS app and ran into an issue where I can’t enable Developer Mode on my Apple Watch.
Device info:
Apple Watch Series 9 (watchOS 10.4)
Paired with iPhone 14 Pro (iOS 17.4.1)
Xcode 15.3 (macOS 15.5, Apple Silicon)
Issue:
When I try to run the app on my physical watch device, Xcode prompts that Developer Mode needs to be enabled. However, there is no approval request on the Apple Watch, and no Developer Mode option appears under Settings → Privacy & Security.
I’ve already tried the following:
Rebooting both devices
Unpairing and re-pairing the watch
Erasing and setting up the watch again
Signing out and back into my Apple ID
Using the latest Xcode version (15.3 and 16.3 both tested)
Running clean builds and checking provisioning profiles
Attempting install via both simulator and physical device
Still no luck — the app will not launch on the Apple Watch due to Developer Mode being disabled, and the option is missing entirely from Settings.
I visited an Apple Store Genius Bar, but they couldn’t help and told me to contact Developer Support. I’ve already submitted a support request, but in the meantime I wanted to ask here in case anyone else has experienced this and found a workaround.
Thanks in advance.
I am integrating On Demand Resources into my Unity game. The resources install without any problems if the internet connection is stable: all resources are installed. While testing various scenarios without an internet connection, I encountered the following problem: if I turn off the internet during installation, I don't get any error messages, but if I turn the internet back on, the download no longer continues (and I still don't get an error). If I reopen the application with a stable internet connection, the download will always be at 0%. Please tell me what I am doing wrong.
#import "Foundation/Foundation.h"
#if ENABLE_IOS_ON_DEMAND_RESOURCES
#import "Foundation/NSBundle.h"
#endif
#include <string.h>
struct CustomOnDemandResourcesRequestData;
typedef void (*CustomOnDemandResourcesRequestCompleteHandler)(struct CustomOnDemandResourcesRequestData* handler, const char* error);
#if ENABLE_IOS_ON_DEMAND_RESOURCES
struct CustomOnDemandResourcesRequestData
{
NSBundleResourceRequest* request;
};
extern "C" CustomOnDemandResourcesRequestData* CustomOnDemandResourcesCreateRequest(const char* const* tags, int tagCount, CustomOnDemandResourcesRequestCompleteHandler handler)
{
NSMutableArray* tagArray = [NSMutableArray array];
for (int i = 0; i < tagCount; i++) {
const char* tag = tags[i];
if (tag != NULL) {
[tagArray addObject:[NSString stringWithUTF8String:tag]];
}
}
NSSet* tagSet = [NSSet setWithArray:tagArray];
CustomOnDemandResourcesRequestData* data = new CustomOnDemandResourcesRequestData();
data->request = [[NSBundleResourceRequest alloc] initWithTags:tagSet];
[data->request beginAccessingResourcesWithCompletionHandler:^(NSError* error) {
dispatch_async(dispatch_get_main_queue(), ^{
const char* errorMessage = error ? [[error localizedDescription] UTF8String] : NULL;
handler(data, errorMessage);
});
}];
return data;
}
extern "C" void CustomOnDemandResourcesRelease(CustomOnDemandResourcesRequestData* data)
{
[data->request endAccessingResources];
delete data;
}
extern "C" float CustomOnDemandResourcesGetProgress(CustomOnDemandResourcesRequestData* data)
{
return data->request.progress.fractionCompleted;
}
extern "C" float CustomOnDemandResourcesGetLoadingPriority(CustomOnDemandResourcesRequestData* data)
{
float priority = (float)data->request.loadingPriority;
return priority;
}
extern "C" void CustomOnDemandResourcesSetLoadingPriority(CustomOnDemandResourcesRequestData* data, float priority)
{
if (priority < 0.0f)
priority = 0.0f;
if (priority > 1.0f)
data->request.loadingPriority = NSBundleResourceRequestLoadingPriorityUrgent;
else
data->request.loadingPriority = (double)priority;
}
extern "C" const char* CustomOnDemandResourcesGetResourcePath(CustomOnDemandResourcesRequestData * data, const char* resource)
{
NSString* resourceStr = [NSString stringWithUTF8String: resource];
NSString* path = [[data->request bundle] pathForResource: resourceStr ofType: nil];
if (path == nil) {
return NULL; // или другое значение по умолчанию
}
const char* result = strdup([path UTF8String]); // копируем строку
return result; // в C# нужно будет освободить память
}
extern "C" void CustomOnDemandResourcesFreeString(const char* str) {
free((void*)str);
}
#else // ENABLE_IOS_ON_DEMAND_RESOURCES
struct CustomOnDemandResourcesRequestData
{
};
extern "C" CustomOnDemandResourcesRequestData* CustomOnDemandResourcesCreateRequest(const char* const* tags, int tagCount, CustomOnDemandResourcesRequestCompleteHandler handler)
{
CustomOnDemandResourcesRequestData* data = new CustomOnDemandResourcesRequestData();
if (handler)
handler(handlerData, NULL);
return data;
}
extern "C" void CustomOnDemandResourcesRelease(CustomOnDemandResourcesRequestData* data)
{
delete data;
}
extern "C" float CustomOnDemandResourcesGetProgress(CustomOnDemandResourcesRequestData* data)
{
return 0.0f;
}
extern "C" float CustomOnDemandResourcesGetLoadingPriority(CustomOnDemandResourcesRequestData* data)
{
return 0.0f;
}
extern "C" void CustomOnDemandResourcesSetLoadingPriority(CustomOnDemandResourcesRequestData* data, float priority)
{
}
extern "C" const char* CustomOnDemandResourcesGetResourcePath(CustomOnDemandResourcesRequestData * data, const char* resource)
{
return NULL;
}
extern "C" void CustomOnDemandResourcesFreeString(const char* str) {
}
#endif // ENABLE_IOS_ON_DEMAND_RESOURCES
Im getting this specific error 'Apple 403 detected - Access forbidden' when trying to build my app, my previous 10 builds all succesfully work but now it keeps on giving this error. I'm guessing its because of a new agreement email I recieved. But when i got to both developer website and app store connect there is no new agreements to accept. I'm quite stuck. Any help appreciated. Thanks
Topic:
Developer Tools & Services
SubTopic:
General
I'm trying to authenticate to a git host using SSH keys stored in 1Password. I have ~/.ssh/config with mode 600 set with a symlink:
Host *
IdentityAgent "~/.1password/agent.sock"
But ssh-add -l shows no identities. If I set $SSH_AUTH_SOCK, ssh-add -l works just fine. I'd love to not have to do this, though.
Why doesn't ssh-add seem to read ~/.ssh/config? The built-in version is OpenSSH_10.0p2, LibreSSL 3.3.6.
I've searched fruitlessly for an answer anywhere else.
I am located in Taiwan and recently updated my Mac to the latest OS and installed the newest Xcode. However, I’m experiencing extremely slow download speeds when trying to add the iOS 26.2 Simulator Runtime (approx. 8GB) via Xcode > Settings > Platforms.
It is currently downloading at a rate of only 500MB per hour, which is impractical. I have checked the official downloads page but couldn't find a standalone DMG link for this specific version.
My questions are:
Is there a direct download link (DMG) available on the Apple Developer portal for the iOS 26.2 Simulator?
If no direct link exists, are there any recommended methods to accelerate the download? (e.g., using terminal commands or changing DNS settings).
Any help or direct URLs would be greatly appreciated. Thank you!
In the online documentation for InstallerJS, it is stated that the unit for the availableKilobytes property of the target field is kilobytes.
Isn't it actually bytes because of a bug in the very first release of macOS that supported InstallerJS?
[Q] Has there been a fix in the recent years regarding this property that would explain why the documentation says it's kilobytes? Even though at the time of this writing, the unit is still bytes when you call my.target.availableKilobytes
I'm using this call to dump the value of this property in install.log:
system.log(my.target.availableKilobytes + '');
Ref. https://developer.apple.com/documentation/installer_js/target/1811975-availablekilobytes
(FB20448952)
I have a Apple Developer accounts for development purposes only and that is also used for testing builds via TestFlight. Is the Age Ratings Responses updates due by the end of January 2026 still required even to send builds to TestFlight?
I need to install the AirPlay profile on an iphone to watch decrypted traffic in ATS for development work on CarPlay.
The documentation for ATS says to click "Utilities -> Download Profiles -> AirPlay Diagnostic Mode".
When I do this, it brings up a file dialog, presumably to select a location to download. But nothing happens. The other profiles launch a web browser and download the .mobileconfig profile.
How do I get the AirPlay profile? Am I misunderstanding how this is supposed to work?
I found ATSAssetsInfoDefault.plist which references these files. And they all have https://developer.apple.com/services-account/download?path=/iOS/iOS_Logs/... except the AirPlay profile, which is type "slug" and just says ats-airplay-diagnostic-mode-profile.
Is this a bug in the app?
I am running into an issue where when layers are grouped, the icon is not shown as it does within the preview in the Icon Composer app
Is this a bug or is it some setting within the group/app?
Recently a bunch of folks have asked about why a specific symbol is being referenced by their app. This is my attempt to address that question.
If you have questions or comments, please start a new thread. Tag it with Linker so that I see it.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Determining Why a Symbol is Referenced
In some situations you might want to know why a symbol is referenced by your app. For example:
You might be working with a security auditing tool that flags uses of malloc.
You might be creating a privacy manifest and want to track down where your app is calling stat.
This post is my attempt at explaining a general process for tracking down the origin of these symbol references. This process works from ‘below’. That is, it works ‘up’ from you app’s binary rather than ‘down’ from your app’s source code. That’s important because:
It might be hard to track down all of your source code, especially if you’re using one or more package management systems.
If your app has a binary dependency on a static library, dynamic library, or framework, you might not have access to that library’s source code.
IMPORTANT This post assumes the terminology from An Apple Library Primer. Read that before continuing here.
The general outline of this process is:
Find all Mach-O images.
Find the Mach-O image that references the symbol.
Find the object files (.o) used to make that Mach-O.
Find the object file that references the symbol.
Find the code within that object file.
Those last few steps require some gnarly low-level Mach-O knowledge. If you’re looking for an easier path, try using the approach described in the A higher-level alternative section as a replacement for steps 3 through 5.
This post assumes that you’re using Xcode. If you’re using third-party tools that are based on Apple tools, and specifically Apple’s linker, you should be able to adapt this process to your tooling. If you’re using a third-party tool that has its own linker, you’ll need to ask for help via your tool’s support channel.
Find all Mach-O images
On Apple platforms an app consists of a number of Mach-O images. Every app has a main executable. The app may also embed dynamic libraries or frameworks. The app may also embed app extensions or system extensions, each of which have their own executable. And a Mac app might have embedded bundles, helper tools, XPC services, agents, daemons, and so on.
To find all the Mach-O images in your app, combine the find and file tools. For example:
% find "Apple Configurator.app" -print0 | xargs -0 file | grep Mach-O
Apple Configurator.app/Contents/MacOS/Apple Configurator: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64]
…
Apple Configurator.app/Contents/MacOS/cfgutil: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
…
Apple Configurator.app/Contents/Extensions/ConfiguratorIntents.appex/Contents/MacOS/ConfiguratorIntents: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
…
Apple Configurator.app/Contents/Frameworks/ConfigurationUtilityKit.framework/Versions/A/ConfigurationUtilityKit: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64]
…
This shows that Apple Configurator has a main executable (Apple Configurator), a helper tool (cfgutil), an app extension (ConfiguratorIntents), a framework (ConfigurationUtilityKit), and many more.
This output is quite unwieldy. For nicer output, create and use a shell script like this:
% cat FindMachO.sh
#! /bin/sh
# Passing `-0` to `find` causes it to emit a NUL delimited after the
# file name and the `:`. Sadly, macOS `cut` doesn’t support a nul
# delimiter so we use `tr` to convert that to a DLE (0x01) and `cut` on
# that.
#
# Weirdly, `find` only inserts the NUL on the primary line, not the
# per-architecture Mach-O lines. We use that to our advantage, filtering
# out the per-architecture noise by only passing through lines
# containing a DLE.
find "$@" -type f -print0 \
| xargs -0 file -0 \
| grep -a Mach-O \
| tr '\0' '\1' \
| grep -a $(printf '\1') \
| cut -d $(printf '\1') -f 1
Find the Mach-O image that references the symbol
Once you have a list of Mach-O images, use nm to find the one that references the symbol. The rest of this post investigate a test app, WaffleVarnishORama, that’s written in Swift but uses waffle management functionality from the libWaffleCore.a static library. The goal is to find the code that calls calloc.
This app has a single Mach-O image:
% FindMachO.sh "WaffleVarnishORama.app"
WaffleVarnishORama.app/WaffleVarnishORama
Use nm to confirm that it references calloc:
% nm "WaffleVarnishORama.app/WaffleVarnishORama" | grep "calloc"
U _calloc
The _calloc symbol has a leading underscore because it’s a C symbol. This convention dates from the dawn of Unix, where the underscore distinguish C symbols from assembly language symbols.
The U prefix indicates that the symbol is undefined, that is, the Mach-O images is importing the symbol. If the symbol name is prefixed by a hex number and some other character, like T or t, that means that the library includes an implementation of calloc. That’s weird, but certainly possible. OTOH, if you see this then you know this Mach-O image isn’t importing calloc.
IMPORTANT If this Mach-O isn’t something that you build — that is, you get this Mach-O image as a binary from another developer — you won’t be able to follow the rest of this process. Instead, ask for help via that library’s support channel.
Find the object files used to make that Mach-O image
The next step is to track down which .o file includes the reference to calloc. Do this by generating a link map. A link map is an old school linker feature that records the location, size, and origin of every symbol added to the linker’s output.
To generate a link map, enable the Write Link Map File build setting. By default this puts the link map into a text (.txt) file within the derived data directory. To find the exact path, look at the Link step in the build log. If you want to customise this, use the Path to Link Map File build setting.
A link map has three parts:
A simple header
A list of object files used to build the Mach-O image
A list of sections and their symbols
In our case the link map looks like this:
# Path: …/WaffleVarnishORama.app/WaffleVarnishORama
# Arch: arm64
# Object files:
[ 0] linker synthesized
[ 1] objc-file
[ 2] …/AppDelegate.o
[ 3] …/MainViewController.o
[ 4] …/libWaffleCore.a[2](WaffleCore.o)
[ 5] …/Foundation.framework/Foundation.tbd
…
# Sections:
# Address Size Segment Section
0x100008000 0x00001AB8 __TEXT __text
…
The list of object files contains:
An object file for each of our app’s source files — That’s AppDelegate.o and MainViewController.o in this example.
A list of static libraries — Here that’s just libWaffleCore.a.
A list of dynamic libraries — These might be stub libraries (.tbd), dynamic libraries (.dylib), or frameworks (.framework).
Focus on the object files and static libraries. The list of dynamic libraries is irrelevant because each of those is its own Mach-O image.
Find the object file that references the symbol
Once you have list of object files and static libraries, use nm to each one for the calloc symbol:
% nm "…/AppDelegate.o" | grep calloc
% nm "…/MainViewController.o" | grep calloc
% nm "…/libWaffleCore.a" | grep calloc
U _calloc
This indicates that only libWaffleCore.a references the calloc symbol, so let’s focus on that.
Note As in the Mach-O case, the U prefix indicates that the symbol is undefined, that is, the object file is importing the symbol.
Find the code within that object file
To find the code within the object file that references the symbol, use the objdump tool. That tool takes an object file as input, but in this example we have a static library. That’s an archive containing one or more object files. So, the first step is to unpack that archive:
% mkdir "libWaffleCore-objects"
% cd "libWaffleCore-objects"
% ar -x "…/libWaffleCore.a"
% ls -lh
total 24
-rw-r--r-- 1 quinn staff 4.1K 8 May 11:24 WaffleCore.o
-rw-r--r-- 1 quinn staff 56B 8 May 11:24 __.SYMDEF SORTED
There’s only a single object file in that library, which makes things easy. If there were a multiple, run the following process over each one independently.
To find the code that references a symbol, run objdump with the -S and -r options:
% xcrun objdump -S -r "WaffleCore.o"
…
; extern WaffleRef newWaffle(void) {
0: d10083ff sub sp, sp, #32
4: a9017bfd stp x29, x30, [sp, #16]
8: 910043fd add x29, sp, #16
c: d2800020 mov x0, #1
10: d2800081 mov x1, #4
; Waffle * result = calloc(1, sizeof(Waffle));
14: 94000000 bl 0x14 <ltmp0+0x14>
0000000000000014: ARM64_RELOC_BRANCH26 _calloc
…
Note the ARM64_RELOC_BRANCH26 line. This tells you that the instruction before that — the bl at offset 0x14 — references the _calloc symbol.
IMPORTANT The ARM64_RELOC_BRANCH26 relocation is specific to the bl instruction in 64-bit Arm code. You’ll see other relocations for other instructions. And the Intel architecture has a whole different set of relocations. So, when searching this output don’t look for ARM64_RELOC_BRANCH26 specifically, but rather any relocation that references _calloc.
In this case we’ve built the object file from source code, so WaffleCore.o contains debug symbols. That allows objdump include information about the source code context. From that, we can easily see that calloc is referenced by our newWaffle function.
To see what happens when you don’t have debug symbols, create an new object file with them stripped out:
% cp "WaffleCore.o" "WaffleCore-stripped.o"
% strip -x -S "WaffleCore-stripped.o"
Then repeat the objdump command:
% xcrun objdump -S -r "WaffleCore-stripped.o"
…
0000000000000000 <_newWaffle>:
0: d10083ff sub sp, sp, #32
4: a9017bfd stp x29, x30, [sp, #16]
8: 910043fd add x29, sp, #16
c: d2800020 mov x0, #1
10: d2800081 mov x1, #4
14: 94000000 bl 0x14 <_newWaffle+0x14>
0000000000000014: ARM64_RELOC_BRANCH26 _calloc
…
While this isn’t as nice as the previous output, you can still see that newWaffle is calling calloc.
A higher-level alternative
Grovelling through Mach-O object files is quite tricky. Fortunately there’s an easier approach: Use the -why_live option to ask the linker why it included a reference to the symbol. To continue the above example, I set the Other Linker Flags build setting to -Xlinker / -why_live / -Xlinker / _calloc and this is what I saw in the build transcript:
_calloc from /usr/lib/system/libsystem_malloc.dylib
_newWaffle from …/libWaffleCore.a[2](WaffleCore.o)
_$s18WaffleVarnishORama18MainViewControllerC05tableE0_14didSelectRowAtySo07UITableE0C_10Foundation9IndexPathVtFTf4dnn_n from …/MainViewController.o
_$s18WaffleVarnishORama18MainViewControllerC05tableE0_14didSelectRowAtySo07UITableE0C_10Foundation9IndexPathVtF from …/MainViewController.o
Demangling reveals a call chain like this:
calloc
newWaffle
WaffleVarnishORama.MainViewController.tableView(_:didSelectRowAt:)
WaffleVarnishORama.MainViewController.tableView(_:didSelectRowAt:)
and that should be enough to kick start your investigation.
IMPORTANT The -why_live option only works if you dead strip your Mach-O image. This is the default for the Release build configuration, so use that for this test.
Revision History
2025-07-18 Added the A higher-level alternative section.
2024-05-08 First posted.
In our Unity App for iOS build, when we opened the PDF from the app, it is automatically opening in landspace mode instead of portrait. In the android and windows apps, we are able to open in the portrait mode. We tried to make the changes in the project settings but it did not change.
Any way in which we can acheive this would be helpful for us.
Hello Apple community !
Not here to report an issue but I just wanted to make a suggestion ^^
I feel like a common frustration amongst developers is the lack of transparency over bugs filed on developer tools, SDKs, iOS versions, the whole Apple ecosystem really.
This leads to the creation of parallel bug tracking tools (https://github.com/feedback-assistant/reports?tab=readme-ov-file /
https://openradar.appspot.com/page/1) or filing of duplicates for reports that may already exist and are being worked on.
I feel like this would save time for both external developers that encounter bugs & Apple engineers that have to look for possible duplicates to share a common public database of issues.
Other companies have this kind of system in place (Google for example : https://issuetracker.google.com/) so why not Apple ?
Thank you
Hi,
I'm generating MusicKit JWT tokens on my backend side and using it on the client side to query the Apple Music API. One concern I have is accidentally over issuing the scope of this JWT, resulting in accidental access more services than intended like DeviceCheck or APNS.
Other than using separate keys for MusicKit and other services, is there a way to limit the generated JWT to only the Apple Music API (https://api.music.apple.com/v1/*) using the JWT payload scope?
Topic:
Developer Tools & Services
SubTopic:
General
Tags:
Apple Music API
MusicKit
App Store Connect API
I am developing an iOS in-app SDK for collecting code coverage data. The SDK writes coverage data to a specified file by calling __llvm_profile_set_filename and __llvm_profile_write_file. This implementation worked correctly until I switched to Xcode 26.0 to build my project. Now, when __llvm_profile_write_file() is executed, it crashes with the following error stack. Can anyone provide any assistance?
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000001
Exception Codes: 0x0000000000000001, 0x0000000000000001
Termination Reason: Namespace SIGNAL, Code 11, Segmentation fault: 11
Terminating Process: exc handler [454]
Thread 96 name: Dispatch queue: com.test-coverage.processing
Thread 96: Crashed:
0 Demo 0x122602ea8 initializeValueProfRuntimeRecord (in Demo) (InstrProfilingValue.c:351)
1 Demo 0x00000001226064c0 writeOneValueProfData (in Demo) (InstrProfilingWriter.c:153)
2 Demo 0x0000000122606308 writeValueProfData (in Demo) (InstrProfilingWriter.c:234)
3 Demo 0x00000001226060d0 lprofWriteDataImpl (in Demo) (InstrProfilingWriter.c:401)
4 Demo 0x0000000122605d98 lprofWriteData (in Demo) (InstrProfilingWriter.c:261)
5 Demo 0x0000000122604804 writeFile (in Demo) (InstrProfilingFile.c:536)
6 Demo 0x122604664 __llvm_profile_write_file_alias + 228
7 Demo 0x000000011c6dd108 -[BDTestCoverage p_dumpMainCoverageInfoWithCustomKey:] (in Demo) (TestCoverage.m:995)
8 Demo 0x000000011c6dcef8 -[BDTestCoverage p_dumpAllCoverageProfileWithCustomKey:] (in Demo) (TestCoverage.m:970)
I regularly bump into folks confused by this issue, so I thought I’d collect my thoughts on the topic into a single (hopefully) coherent post.
If you have questions or comments, put them in a new thread here on the forums. Feel free to use whatever subtopic and tags that apply to your situation, but make sure to add the Debugging tag so that I see your thread go by.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Testing and Debugging Code Running in the Background
I regularly see questions like this:
My background code works just fine in Xcode but fails when I download the app from the App Store.
or this:
… or fails when I run my app from the Home screen.
or this:
How do I step through my background code?
These suggest a fundamental misunderstanding of how the debugger interacts with iOS’s background execution model. The goal of this post is to explain that misunderstanding so that you can effectively test and debug background code.
Note The focus of this post is iOS. The advice here generally applies to any of iOS’s ‘child’ platforms, so iPadOS, tvOS, and so on. However, there will be some platform specific differences, especially on watchOS. This advice here doesn’t apply to macOS. It’s background execution model is completely different than the one used by iOS.
Understand the Fundamentals
The key point to note here is that the debugger prevents your app from suspending. This has important consequences for iOS’s background execution model. Normally:
iOS suspends your app when it’s in the background.
Once your app is suspended, it becomes eligible for termination. The most common reason for this is that the system wants to recover memory, but it can happen for various other reasons. For example, the system might terminate a suspended app in order to update it.
Under various circumstances your app can continue running after moving to the background. A great example of this is the continued processed task feature, introduced in iOS 26 beta.
Alternatively, your app can be resumed or relaunched in the background to perform some task. For example, the region monitor feature of Core Location can resume or relaunch your app in the background when the user enters or leaves a region.
If no app needs to be executing, the system can sleep the CPU.
None of this happens in the normal way if the debugger is attached to your app, and it’s vital that you take that into account when debugging code that runs in the background.
An Example of the Problem
For an example of how this can cause problems, imagine an app that uses an URLSession background session. A background session will resume or relaunch your app in the background when specific events happen. This involves two separate code paths:
If your app is suspended, the session resumes it in the background.
If your app is terminated, it relaunches it in the background.
Neither code path behaves normally if the debugger is attached. In the first case, the app never suspends, so the resume case isn’t properly exercised. Rather, your background session acts like it would if your app were in the foreground. Normally this doesn’t cause too many problems, so this isn’t a huge concern.
On the other hand, the second case is much more problematic. The debugger prevents your app from suspending, and hence from terminating, and thus you can’t exercise this code path at all.
Seek Framework-Specific Advice
The above is just an example, and there are likely other things to keep in mind when debugging background code for a specific framework. Consult the documentation for the framework you’re working with to see if it has specific advice.
Note For URLSession background sessions, check out Testing Background Session Code.
The rest of this post focuses on the general case, offering advice that applies to all frameworks that support background execution.
Run Your App Outside of Xcode
When debugging background execution, launch your app from the Home screen. For day-to-day development:
Run the app from Xcode in the normal way (Product > Run).
Stop it.
Run it again from the Home screen.
Alternatively, install a build from TestFlight. This accurately replicates the App Store install experience.
Write Code with Debugging in Mind
It’s obvious that, if you run the app without attaching the debugger, you won’t be able to use the debugger to debug it. Rather:
Extract the core logic of your code into libraries, and then write extensive unit tests for those libraries. You’ll be able to debug these unit tests with the debugger.
Add log points to help debug your integration with the system.
Treat your logging as a feature of your product. Carefully consider where to add log points and at what level to log. Check this logging code into your source code repository and ship it — or at least the bulk of it — as part of your final product. This logging will be super helpful when it comes to debugging problems that only show up in the field.
My general advice is that you use the system log for these log points. See Your Friend the System Log for lots of advice on that front.
One of the great features of the system log is that disabled log points are very cheap. In most cases it’s fine to leave these in your final product.
Attach and Detach
In some cases it really is helpful to debug with the debugger. One option here is to attach to your running app, debug a specific thing, and then detach from it. Specifically:
To attach to a running app, choose Debug > Attach to Process > YourAppName in Xcode.
To detach, choose Debug > Detach.
Understand Force Quit
iOS allows users to remove an app from the multitasking UI. This is commonly known as force quit, but that’s not a particularly accurate term:
The multitasking UI doesn’t show apps that are running, it shows apps that have been run by the user. The UI shows recently run apps regardless of whether they’re in the foreground, running in the background, suspended, or terminated. So, removing an app from the UI may not actually quit anything.
Removing an app sets a flag that prevents the app from being launched in the background. That flag gets cleared when the user next launches the app manually.
Note In some circumstances iOS will not honour this flag. The exact cases where this happens are not documented and have changed over time.
Keep these behaviours in mind as you debug your background execution code. For example, imagine you’re trying to test the URLSession background relaunch code path discussed above. If you force quit your app, you’ll never hit this code path because iOS won’t relaunch your app in the background. Rather, add a debug-only button that causes your app to call exit.
IMPORTANT This suggestion is for debugging only. Don’t include a Quit button in your final app! This is specifically proscribed by QA1561.
Alternatively, if you’re attached to your app with Xcode, simply choose Product > Stop. This is like calling exit; it has no impact on your app’s ability to run in the background.
Test With Various Background App Refresh Settings
iOS puts users in control of background execution via the options in Settings > General > Background App Refresh. Test how your app performs with the following settings:
Background app refresh turned off overall
Background app refresh turned on in general but turned off for your app
Background app refresh turned on in general and turned on for your app
IMPORTANT While these settings are labelled Background App Refresh, they affect subsystems other than background app refresh. Test all of these cases regardless of what specific background execution feature you’re using.
Test Realistic User Scenarios
In many cases you won’t be able to fully test background execution code at your desk. Rather, install a TestFlight build of your app and then use the device as a normal user would. For example:
To test Core Location background execution properly, actual leave your office and move around as a user might.
To test background app refresh, use your app regularly during the day and then put your device on charge at night.
Testing like this requires two things:
Patience
Good logging
The system log may be sufficient here, but you might need to investigate other logging solutions that are more appropriate for your product.
These testing challenges are why it’s critical that you have unit tests to exercise your core logic. It takes a lot of time to run integration tests like this, so you want to focus on integration issues. Before starting your integration tests, make sure that your unit tests have flushed out any bugs in your core logic.
Revision History
2025-08-12 Made various editorial changes.
2025-08-11 First posted.
There is a bug in Unity Plugins: Corehaptics.AssetPickerDrawer throws exceptions and draws incorrectly when fieldInfo or assetType is null (FB17305973). I fixed it and created a pull request: https://github.com/apple/unityplugins/pull/47
It has been months and this bug is really annoying.
Topic:
Developer Tools & Services
SubTopic:
General
Tags:
Prototyping
Core Haptics
Apple Unity Plug-Ins
The app I'm working on has iOS 16.0 as target. Recently Live Activities support was added, but then it started crashing when running on iOS 16.0 devices.
After some investigation, I've found that the culprit was the presence of NSUserActivityTypeLiveActivity and WidgetCenter.UserInfoKey.activityID, even though they were inside an @available(iOS 17.2, *) block. If I comment these two variables, the app work as expected. I've also tried adding #if canImport(ActivityKit) around the code, but without success.
But if the @available isn't working, how can I prevent this? It looks like a bug, since the documentation says that NSUserActivityTypeLiveActivity is supported but iOS 14.0+, but I'm pretty sure it was introduced on 16.1.
This is the only output I get with the crash:
dyld[66888]: Symbol not found: _$s9WidgetKit0A6CenterC11UserInfoKeyV10activityIDSSvgZ
Referenced from: <D6EFF120-2681-34C1-B261-8F3F7B388238> /Users/<redacted>/Library/Developer/CoreSimulator/Devices/8B5B4DC9-3D54-4C91-8C88-E705E851CA0F/data/Containers/Bundle/Application/DB6671FF-CB07-4570-BD63-C851D94FAF29/<redacted>.app/<redacted>.debug.dylib
Expected in: <C5E72BB5-533F-3658-A987-E849888F4DFC> /Library/Developer/CoreSimulator/Volumes/iOS_20A360/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 16.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/WidgetKit.framework/WidgetKit
Hello,
I'm building this mobile app using Quasar - Capacitor on iOS.
The app is working perfectly, but I'm encountering an issue whenever I push the rep I get this error: "Error
Unable to open base configuration reference file '/Volumes/workspace/repository/ios/App/Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig'.
App.xcodeproj:1"
I've tried every possible solution and made sure that everything is set perfectly.
Can anyone please help me with that?
Thanks in advance, appreciate you 🫶🏻