22

Note:

This is not a duplicate of the linked questions

Goal:

  • I am not looking for a print vs NSLog differences
  • In fact I don't want to use either of them (presently using print)
  • I am looking for an Apple recommended way, just can't seem to find the command / documentation, I just know it exists.

Present implementation:

Presently I am using print statements with some global functions

Question

  1. What is the recommended way / approach to handle errors (I don't want to use NSLog as they would write into the device's console)
  2. This is only for debugging purposes during development
Community
  • 1
  • 1
user1046037
  • 16,755
  • 12
  • 92
  • 138
  • 2
    Make sure you check `os.log`. You can use its results during debug and release. see [here](https://stackoverflow.com/q/45353818/5175709) – mfaani Jun 06 '18 at 19:53
  • This seems like a great opportunity to incorporate open source software like [CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack), which has macros like `DDLogError`, `DDLogWarn`, `DDLogInfo`, etc. – Michael Dautermann Jun 06 '18 at 20:00
  • @Honey `os.log` seems interesting, thanks, could you post it as an answer, exactly what I was looking for – user1046037 Jun 06 '18 at 20:23
  • For now you can use https://github.com/apple/swift-log – onmyway133 Apr 01 '19 at 10:37

1 Answers1

33

Take a look at os_log. It offers all the things you're looking for.

NEW STUFF

Also the more easier to use Logger API available since iOS14. See here as well

Since iOS15 you can also retrieve the logs using OSLogStore . See here.

Also see Acquiring Crash Reports and Diagnostic Logs


Disclaimer:

I highly recommend you see this thread from Swift forums. tl;dr

Even though it's' Apple's recommendation, its usage is debated due to concerns about retrieving logs:

  • retrieving logs is not a trivial process. It's actually difficult. See here
  • For most users the log file can be 100-300 Mbs. Which makes it hard to send.

It's great for debugging during development, but laborious to trigger, retrieve, send by your app users.


Example:

let customLog = OSLog(subsystem: "com.your_company.your_subsystem_name", category: "Category")
os_log("This is info that may be helpful during development or debugging.", log: customLog, type: .debug)

Some great references:

  • WWDC 2016 Unified Logging and Tracing.
  • This answer by Rob. He discusses that NSLog is deprecated and some of the benefits of using the new os_log library.
  • You can also get the logs from using the approach mentioned here. Make sure you see ? answers.

The reason os_log is so powerful is because:

  • offers different log levels
  • has different categories
  • private and public logs
  • it's lightweight and built by Apple. Doesn't require pods
  • unlike print which is only available during debugging, os_log can be used to peek into a released app (in realtime) and view the logs in the console app.

enter image description here

This is great for observing application life cycle changes free of the greedy Xcode i.e. if you’re debugging while connected to Xcode , then Xcode doesn’t allow the app to be put in a suspended state...


Note: os_log is only available to +iOS10

There are new videos as well from WWDC 2018 and 2019, but have a higher focus on os_signpost. See:

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • Hello , how to read os_log after release my app ?? – a.masri Dec 22 '18 at 14:33
  • You either need the actual device or the sysdiagnose. See [here](https://stackoverflow.com/questions/45353818/how-can-i-open-view-ios-oslogs-stored-on-device/45381965#45381965) – mfaani Dec 22 '18 at 14:56
  • thank you , Can users send it to me via mail? like log.txt file ?? – a.masri Dec 22 '18 at 17:17
  • It would be 100-300Mb file. So no. They can use Dropbox. But the process of creating a sysdiagnose and sending it is not something most users are capable of. I actually wonder which users Apple thinks will use this... – mfaani Dec 22 '18 at 20:56
  • 2
    One problem with using os_log is that you cannot pass dynamic strings so you can't hide it inside your own debug function taking params from outside. You have to use it explicitly in your code, eg: os_log("User %{PRIVATE}@ logged in", log: OSLog.userFlow, type: .info, username) there's 12/2018 proposal to alleviate this https://forums.swift.org/t/custom-string-interpolation-and-compile-time-interpretation-applied-to-logging/18799/7 – Andy Dent Jun 22 '19 at 09:35