Logging

It‘s best to change the log level early on, for example in -[UIApplicationDelegate application:didFinishLaunchingWithOptions:].

The default log level is PSPDFLogLevelMaskInfo|PSPDFLogLevelMaskWarning|PSPDFLogLevelMaskError|PSPDFLogLevelMaskCritical:

1
2
// Change log level to be more verbose.
PSPDFKit.sharedInstance.logLevel = [.info, .warning, .error, .critical]
Copy
1
2
// Change log level to be more verbose.
PSPDFKit.sharedInstance.logLevel = PSPDFLogLevelMaskInfo|PSPDFLogLevelMaskWarning|PSPDFLogLevelMaskError|PSPDFLogLevelMaskCritical;

Available Log Levels:

  • PSPDFLogLevelMaskNothing
  • PSPDFLogLevelMaskCritical
  • PSPDFLogLevelMaskError
  • PSPDFLogLevelMaskWarning
  • PSPDFLogLevelMaskInfo
  • PSPDFLogLevelMaskDebug
  • PSPDFLogLevelMaskVerbose
  • PSPDFLogLevelMaskAll

If you want to learn more about the different log levels, please take a look at PSPDFLogLevelMask.

Custom Log Handler

PSPDFKit also allows you to set a custom log handler to forward logging to a different system. By default, NSLog is used for logging. Here‘s how you can set a different log handler:

Copy
1
2
3
4
5
6
7
8
PSPDFKit.sharedInstance.logHandler = { level, tag, message, file, function, line in
    switch level {
    case .error:
        print("[PSPDFKit] Error in \(function): \(message())")
    default:
        print("[PSPDFKit] \(message())")
    }
}
Copy
1
2
3
4
5
6
7
8
9
10
11
[PSPDFKit.sharedInstance setLogHandler:^(PSPDFLogLevelMask level, const char *tag, NSString *(^message)(void), const char *file, const char *function, NSUInteger line) {
    switch (level) {
        case PSPDFLogLevelMaskError:
            NSLog(@"[PSPDFKit] Error in %s: %@", function, message());
            break;

        default:
            NSLog(@"[PSPDFKit] %@", message());
            break;
    };
}];

In this way, you can also report critical logs to your analytics or crash reporting service in order to gain more insight about which logs your users are hitting. You may also capture the current stack trace and attach it to the service you are using:

Copy
1
2
3
4
5
6
7
8
9
10
11
case .critical:
    let functionString = String(cString: function)
    print("[PSPDFKit] \(functionString): \(message())")

    let attributes = [
        "function_name": "\(functionString)/\(line)",
        "message": message(),
        // Capture the stack trace.
        "stack_trace": Thread.callStackSymbols.joined(separator: "\n")
    ]
    Analytics.logCriticalEvent(with: attributes)
Copy
1
2
3
4
5
6
7
8
9
10
case PSPDFLogLevelMaskCritical:
    NSLog(@"[PSPDFKit] %s: %@", function, message());

    NSDictionary<NSString *, NSString *> *attributes = @{
      @"function_name": [NSString stringWithFormat:@"%s/%tu", function, line],
      @"message": message(),
      // Capture the stack trace.
      @"stack_trace": [NSThread.callStackSymbols componentsJoinedByString:@"\n"]
    };
    [Analytics logCriticalEventWithAttributes:attributes];

See -[PSPDFKit logHandler] for more information.