Hello,
I am a student studying accessibility.
I aim to analyze the smartphone usage patterns of visually impaired individuals.
Therefore, I would like to log the VoiceOver usage records of visually impaired iPhone users.
Is there a way to output VoiceOver logs, similar to the AccessibilityService API on Android?
Thank you in advance for your responses.
OSLog
RSS for tagOSLog is a unified logging system for the reading of historical data.
Posts under OSLog tag
38 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Is it just me or does running SwiftUI apps using Xcode 16 give so many warnings and errors in the console that it's impossible to debug everything? Even the simplest gestures such as a long press generate a warning. I'm starting to ignore them, which feels negligent. Any insights/tips?
When I set the option parameter to OSLogEnumeratorReverse, the iteration order of OSLogEnumerator is still from front to back in time
When I set the options parameter to 0 and the position parameter to the first 5 seconds of the current time, OSLogEnumerator can still iterate over the previous 5 seconds
#import "ViewController.h"
#import <OSLog/OSLog.h>
@interface ViewController ()
@property(strong, nonatomic)OSLogStore *logStore;
@property(strong, nonatomic)NSDateFormatter *formatter;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSError *err = nil;
self.logStore = [OSLogStore storeWithScope:OSLogStoreCurrentProcessIdentifier error:&err];
if (!self.logStore || err) {
NSLog(@"error: %@", err);
NSAssert(0, @"");
}
self.formatter = [[NSDateFormatter alloc] init];
[self.formatter setDateFormat:@"[yyyy-MM-dd HH:mm:ss:SSS]"];
}
- (IBAction)addLog:(id)sender {
static int i = 0;
NSLog(@"[test] %@ this is a log with index:%d", [self.formatter stringFromDate:[NSDate date]], i++);
}
- (IBAction)printLogWithReverse:(id)sender {
NSError *err = nil;
NSPredicate *preeicate = [NSPredicate predicateWithFormat:@"composedMessage contains %@" argumentArray:@[@"[test]"]];
OSLogEnumerator *enumer = [self.logStore entriesEnumeratorWithOptions:OSLogEnumeratorReverse position:nil predicate:preeicate error:&err];
if (err) {
NSLog(@"enumer error:%@", err);
NSAssert(0, @"");
}
OSLogEntryLog *entry = nil;
while (entry = [enumer nextObject]) {
NSString *message = [entry composedMessage];
printf("log: %s\n", message.UTF8String);
}
}
- (IBAction)printLogWithPosition:(id)sender {
NSError *err = nil;
NSPredicate *preeicate = [NSPredicate predicateWithFormat:@"composedMessage contains %@" argumentArray:@[@"[test]"]];
NSDate *posDate = [NSDate dateWithTimeIntervalSinceNow:-5];
OSLogPosition *pos = [self.logStore positionWithDate:posDate];
OSLogEnumerator *enumer = [self.logStore entriesEnumeratorWithOptions:0 position:pos predicate:preeicate error:&err];
if (err) {
NSLog(@"enumer error:%@", err);
NSAssert(0, @"");
}
const char *now = [self.formatter stringFromDate:[NSDate date]].UTF8String;
const char *posStart = [self.formatter stringFromDate:posDate].UTF8String;
OSLogEntryLog *entry = nil;
while (entry = [enumer nextObject]) {
NSString *message = [entry composedMessage];
printf("log(now:%s, pos:%s): %s\n", now, posStart, message.UTF8String);
}
}
@end
The method of - (IBAction)printLogWithReverse:(id)sender print result not reversed by time.
log: [test] [2025-02-18 17:35:50:175] this is a log with index:0
log: [test] [2025-02-18 17:35:51:040] this is a log with index:1
log: [test] [2025-02-18 17:35:51:174] this is a log with index:2
log: [test] [2025-02-18 17:35:51:323] this is a log with index:3
log: [test] [2025-02-18 17:35:51:473] this is a log with index:4
log: [test] [2025-02-18 17:35:51:640] this is a log with index:5
log: [test] [2025-02-18 17:35:51:773] this is a log with index:6
log: [test] [2025-02-18 17:35:51:923] this is a log with index:7
The method of - (IBAction)printLogWithPosition:(id) print result should not contain the log from 5 seconds ago because I set the start time position in the position argument
[test] [2025-02-18 17:43:58:741] this is a log with index:0
[test] [2025-02-18 17:43:58:940] this is a log with index:1
[test] [2025-02-18 17:43:59:458] this is a log with index:2
[test] [2025-02-18 17:43:59:923] this is a log with index:3
log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:58:741] this is a log with index:0
log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:58:940] this is a log with index:1
log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:59:458] this is a log with index:2
log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:59:923] this is a log with index:3
Hello, I'm developing a Transparent Proxy and I noticed that the Network Extension Framework logs in the Unified Logging System when my profile receives a flow, its source application, its destination endpoint, and my profile's decision regarding that flow.
I worry that this may compromise the user's privacy. So is there a way that I can turn off these logs at least in Distribution Configurations?
Hello,
I'm seeing many errors like this in the Xcode debug console when I build and run my app:
ERROR: Unrecognized attribute string flag '?' in attribute string "T@"NSString",?,R,C" for property debugDescription
The app project makes heavy use of Logger(), and I suspect it is related to that logging in some way, but I haven't been able to narrow down the issue to specific log calls.
I have Category, Subsystem and Timestamp enabled in the Xcode console, but none of those are displayed for this output.
What causes this? Or how can I better narrow down the source?
Hi: Our group would like to forward logs from our Macs in our integration/production environments to a central server. I haven't found any good documentation for this yet.
Can anyone point me to a way to forward to a Graylog or syslog-based server?
We're not against cobbling together an app or script using "log stream" to send the info ourselves, but that seems extreme for what I'd think is a very common use case.
I have os_log statements in my app. With my phone connected to the Mac, when I run the app through XCode, open Console app, those logs are shown. However, when I'm launching the app on its own, those logs don't appear in Console (phone still connected).
Am I missing something very basic? Please help.
Hi,
I'm developing a multi-platform project in Windows, Mac and Linux. I am trying to create a wrapper class in Go that will query system information and history.
I see that the Unified Logging System is a sophisticated way to get all sorts of kernel information (and even a long history including rotated logs). However, I am struggling to see how I can use the APIs in other languages aside from Swift itself (or C). I do not want to use the log or last commands to query information in separate child processes in my project. I would like to simply query the database itself, similar to using OSLog in Swift.
If this is something that is entirely proprietary or not possible, let me know :)
Hello,
I need to monitor the device for an activity that is not supported by ES framework. I can reliably monitor it using correct filters with log stream, for example
sudo log stream --info --style compact --predicate 'category = "X"'
But I need to provide that functionality through my application. Because of that, I made an instance of a log store, hoping I will be able to retrieve the necessary informations that way. The problem is that the messages are sometimes appearing and sometimes not. The log level I am interested in is info, which according to the docs
The system stores info-level messages in memory buffers and, without a configuration change, purges the oldest messages as those buffers fill up.
If I understand that correctly, the info messages are being written to the buffer and not the store, only sometimes reaching it. But also that should be modifiable with a configuration change? How could I make such change to always save info logs to the store and retrieve them?
I'm trying to diagnose an issue with a Message Filtering Extension not working.
The associated domain for the server is not currently publicly hosted, so the associated domains specified for the app are postpended with
?mode=developer
On application installation I filtered OS logging by the swcd process and saw this logged:
debug 08:40:01.125071-0800 swcd Skipping domain vz….qa….cl….ce….com?mode=developer because developer mode is disabled
But developer mode IS enabled on the phone (Settings/Privacy & Security/Developer Mode is set to On).
Therefore why is swcd saying developer mode is disabled?
Is the developer mode mentioned in the documentation not actually the Developer Mode in the iPhone's setting but something else?
That wouldn't appear to be the case because the documentation explicitly states
"Specifies that only devices in developer mode can access the domain."
Full Documentation: https://developer.apple.com/documentation/BundleResources/Entitlements/com.apple.developer.associated-domains
If you use a private web server, which is unreachable from the public internet, while developing your app, enable the alternate mode feature to bypass the CDN and connect directly to your server. To do this, add a query string to your associated domains entitlement, as shown in the following example:
:?mode=
developer
Specifies that only devices in developer mode can access the domain.
So I've:
turned developer mode on for the device
have added ?mode=developer to the domain
am building/running using a developer certificate.
But why does swcd log that developer mode is disabled?
I'm getting literally hundreds and hundreds of these lines appearing in the Xcode console when running the app.
What's the cause? Too much logging? (if so this didn't used to appear with earlier version of Xcode, I'm currently running Xcode 16.2)
How to do this:
"set IDELogRedirectionPolicy to oslogToStdio in the environment of the executable."
And what does doing that do?
<snip>
1 log/signpost messages lost due to high rates in live mode recording. To guarantee delivery of all logs, set IDELogRedirectionPolicy to oslogToStdio in the environment of the executable.
1 log/signpost messages lost due to high rates in live mode recording. To guarantee delivery of all logs, set IDELogRedirectionPolicy to oslogToStdio in the environment of the executable.
<snip>
Pretty sure this is a no-no, but asking just in case there's an easy way to make this work
struct DocumentContentView: View {
private static let logger = Logger(
subsystem: "mySubsystem",
category: String(describing: Self.self)
)
var body: some View {
VStack {
Text("Hello")
logger.trace("hello")
}
}
}
This code generates the following compile error at the logger.trace line
buildExpression is unavailable: this expression does not conform to View
I suspect every line of the body var (or any @ViewBuilder - designated code?) needs to 'return' a View. Is this correct? or more importantly any work arounds other than putting some/all of the view contents in a. func()?
Something (or a lot) is janky about apps built for "My Mac - designed for iPad."
Aside from things just not working, the amount of garbage spewed to the console during debugging is unmanageable. I can't see my own trace statements amongst screens and screens of repetitive nonsense.
I right-clicked on it and set it to filter out errors, but I'd like to get notified of legitimate errors. Anyone employing a clever filtering method I'm not aware of?
Hello Apple support,
We are trying to figure out how to persist the activity logs and retrieve it. It seems the obvious place to find them is "Analytics & Improvements" in settings.
How are the .ips log generated? (OSLog?)
What are the conditions for the iOS to store the logs?
We are aware of this post, but no info on the storage of logs
Hello,
I am currently working on a project that involves periodically querying OSLog to forward system log entries to a backend. While the functionality generally operates as expected, I have encountered a memory leak in my application. Through testing, I have isolated the issue to the following simplified code example:
#import <Foundation/Foundation.h>
#import <OSLog/OSLog.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
while(1) {
NSError *error = nil;
OSLogStore *logStore = [OSLogStore storeWithScope:OSLogStoreSystem error:&error];
if (!logStore)
NSLog(@"Failed to create log store: %@", error);
sleep(1);
}
}
return 0;
}
When running this example, the application exhibits increasing memory usage, consuming an additional 100 to 200 KB per iteration, depending on whether the build is Debug or Release.
Given that Automatic Reference Counting is enabled, I anticipated that the resources utilized by logStore would be automatically released at the end of each iteration. However, this does not appear to be the case.
Am I using the API wrong?
I would appreciate any insights or suggestions on how to resolve this issue.
Thank you.
I regularly talk to developers debugging hard-to-reproduce problems. I have some general advice on that topic. I’ve posted this to DevForums before, and also sent similar info to folks who’ve opened a DTS incident, but I figured I should write it down properly.
If you have questions or comments, put them in a new thread here on DevForums. Put it in the Developer Tools & Services > General topic area and tag it with Debugging.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem
Some problems are hard to reproduce in your office. These usually fall into one of two categories:
Environment specific — This is where some of your users can easily reproduce the problem, but you can’t reproduce it in your environment.
Intermittent — In this case the problem could affect any user, but it’s hard to predict when a given user will see the problem.
A key tool in debugging such problems is the sysdiagnose log. This post explains how to make this technology work for you.
IMPORTANT A sysdiagnose log might contain private information. If you ask a user to send you a log, make sure they understand the privacy impact of that. If you want to see how Apple handles this, run the sysdiagnose command on a fresh Mac and read through it’s initial prompt.
Sysdiagnose Logs
All Apple platforms can generate sysdiagnose logs. For instructions on how to do this, see our Bug Reporting > Profiles and Logs page.
The resulting log is a .tar.gz file. Unpacking that reveals a bunch of files. The most critical of these is system_logs.logarchive, which is a snapshot of the system log. For more information about the system log, including links to the documentation, see Your Friend the System Log.
This log snapshot includes many thousands of log entries (I just took a log snapshot on my Mac and it had 22.8 million log entries!). That can be rather daunting. To avoid chasing your tail, it pays to do some preparation.
Preparation
The goal here is to create a set of instructions that you can give to your user to capture an actionable sysdiagnose log. That takes some preparation.
To help orient yourself in the log, add log points to your code to highlight the problem. For example, if you’re trying to track down a keychain problem where SecItemCopyMatching intermittently fails with errSecMissingEntitlement ( -34018 ), add a log point like this:
import os.log
let log = Logger(subsystem: "com.example.waffle-varnish", category: "keychain")
func … {
let err = SecItemCopyMatching(…)
log.log("SecItemCopyMatching failed, err: \(err)")
}
When you look through a log, find this specific failure by searching for SecItemCopyMatching failed, err: -34018.
You might also add log points at the start and end of an operation, which helps establish a time range of interest.
Log points like this have a very low overhead and it’s fine to leave them enabled in your released product. However, in some cases you might want to make more extensive changes, creating a debug build specifically to help investigate your problem. Think about how you’re going to get that debug build to the affected users. You might, for example, set up a special TestFlight group for folks who’ve encountered this issue.
Go to Bug Reporting > Profiles and Logs and look for debug profiles that might help your investigation. For example, if you’re investigating a Network Extension issue, the VPN (Network Extension) debug profile will enable useful debug logging.
Now craft your instructions for your user. Include things like:
Your take on the privacy impact on this
Instructions on how to get the necessary build of your product
If there’s a debug profile, instructions on how to install that
Instructions on how to trigger the sysdiagnose log
And on how to send it to you
IMPORTANT Make sure to stress how important it is that the user triggers the sysdiagnose immediately after seeing the problem.
Finally, test your steps. Do an initial test in your office, to make sure that the log captures the info you need. Then do an end-to-end test with someone who’s about as technically savvy as your users, to make sure that your instructions make sense to Real People™.
Prompting for a Sysdiagnose Log
In some cases it might not be obvious to the user when to trigger a sysdiagnose log. Imagine you’re hunting the above-mentioned errSecMissingEntitlement error and it only crops up when your product is performing some task in the background. The user doesn’t see that failure, they’re not even running your app!, so they don’t know that action is required.
A good option here is to add code to actively monitor for the failure and post a local notification requesting that the user trigger a sysdiagnose log. Continuing the above example, you might write code like this:
func … {
let err = SecItemCopyMatching(…)
log.log("SecItemCopyMatching failed, err: \(err)")
if err == errSecMissingEntitlement {
… post a local notification …
}
}
Obviously this is quite intrusive so, depending on the market for your product, you might not want to deploy this to all users. Perhaps you can restrict it to your internal testers, or your external beta testers, or a particularly savvy set of customers.
You can use the applefeedback URL scheme to make it easy for users to run Feedback Assistant. For more info about that, see Developer > Bug Reporting.
Looking at the System Log
Once you have your sysdiagnose log, unpack it and open the system log snapshot (system_logs.logarchive) in Console. The hardest part is knowing where to start. That’s why adding your own log entries, as discussed in Preparation, is so important. A good general process is:
Search for log entries from your subsystem. An easy way to initiate that search is to paste the text subsystem:SSS, where SSS is your subsystem, into the Search field. Continuing the above example, find that log entry by pasting in subsystem:com.example.waffle-varnish.
Identify the log entry that indicates the problem and select it.
Then remove your search and work backwards through the log looking for system log entries related to your issue.
The relevant log entries might not be within the time range shown by Console. Customise that by selecting values from the Showing popup in the pane divider. Once you have a rough idea of the timeframe involved, select Custom from that popup to focus on that range.
If the log is showing stuff that’s not relevant to your problem, Console has some great facilities for filtering those out. For the details, choose Help > Console Help.
Talk to Apple
A key benefit of this approach is that, if your investigation suggests that this is a system bug, you can file a bug report and attach this sysdiagnose log to it. The setup described above is exactly the sort of info needed to analyse the bug.
Likewise, if you start a thread here on DevForums about your issue, your friendly neighbourhood DTS engineer will find that sysdiagnose log very handy.
Revision History
2024-11-14 Added a reference to the applefeedback URL scheme. Made other minor editorial changes.
2023-10-13 First posted.
If an app with a Message Filter Extension is run on an iPhone with iOS 18 installed then there's no logging output to the console (using print or NSLog), however there is logging in all previous versions of OS.
Being able to view logging at run time for this component is essential as a debugging aid to see, for example, if the extension launches, if a text is handled locally or deferred to the network, to see if there's a network error, to examine the server response etc.
Is there a specific reason it was disabled or is it accidental?
Thank you
Requirement:- Crash my MacOs laptop such that my crashes get collected in the /Library/Logs/DiagnosticReports folders. But the crash shouldn't hamper my laptop's performace.
I read that we had an approach to cause a kernel panic, but I'm really concerned about the state that this would put my device in. Any advice would be helpful, thanks.