Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Swift: write print and debug prints into a file

Evening, is it possible to save in a file all the prints and the debug prints?

I would like to have the logs of what my application does even when is not launched from Xcode.

I was thinking to override the print and the debugPrint methods and to write the input into a file.

Thanks

like image 431
Andrea Miotto Avatar asked Nov 20 '18 12:11

Andrea Miotto


People also ask

How do I debug output in Swift?

Logging in Swift Swift provides a default debugging textual representation that you can use for printing any type. The print(_:) or debugPrint(_:) functions can be used to log output from your app to the console for any data type.

What is the use of print statement in SwiftUI?

It is a debugging technique that we can easily carry over to any language and IDE. In UIKit, we use a print statement to trace the flow of execution or stored value. In this example, we print out view variable in a viewDidLoad. Coming from the UIKit world, it might tempting to use print inside a SwiftUI view.

How to use Swift logging in Swift?

You just have to set it up as a dependency in the Package.swift manifest file or you can hook it using Xcode under the File > Swift Packages menu as an SPM dependency. The usage is really straightforward. First you have to import the Logging framework, then you create a logger and you use that logger instance to print out various log messages.

What does debugprint () do in Python?

The print (_:) or debugPrint (_:) functions can be used to log output from your app to the console for any data type. As shown in Figure 1, the debugPrint (_:) function will sometimes display additional information and the dump (_:) function will use the object's mirror to print information to standard output.


3 Answers

There are methods in Swift Standard Library:

func print<Target>(_ items: Any..., separator: String = default, terminator: String = default, to output: inout Target) where Target : TextOutputStream

and

func debugPrint<Target>(_ items: Any..., separator: String = default, terminator: String = default, to output: inout Target) where Target : TextOutputStream

You can create an object that implements TextOutputStream that will save a message to a file of your choice. This is very useful if you already have existing prints in the codebase. You can then just add the additional parameter to them. Remember that those prints will then stop logging to the standard output (console).

Documentation for print

Documentation for debugPrint

Example:

final class LogDestination: TextOutputStream {
  private let path: String
  init() {
    let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    path = paths.first! + "/log"
  }

  func write(_ string: String) {
    if let data = string.data(using: .utf8), let fileHandle = FileHandle(forWritingAtPath: path) {
      defer {
        fileHandle.closeFile()
      }
      fileHandle.seekToEndOfFile()
      fileHandle.write(data)
    }
  }
}

And then

// I would probably use Singleton for this
var dest = LogDestination()
print("My test message", to: &dest)
like image 51
Tomasz Bąk Avatar answered Oct 22 '22 15:10

Tomasz Bąk


Its possible to write all print/debugPrint logs to file in iOS. Use below for writing debug logs to files.

Note: If you are using the below code logs will not print on console.

func writeIntoFile() {
    if let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
        let filePath = documentDirectoryPath + "/logfile.txt"
        freopen(filePath.cString(using: .ascii), "a", stderr)
    }
}
like image 26
iOS_Maccus Avatar answered Oct 22 '22 14:10

iOS_Maccus


I think you want your logs into an external file. If so, then you can try this:

func redirectLogs(flag:Bool)  {
    if flag {
        if let documentsPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
            let logPath = documentsPathString.appending("app.log")
            freopen(logPath.cString(using: String.Encoding.ascii), "a+",stderr)
        }
    }
}
like image 1
Anand Kore Avatar answered Oct 22 '22 14:10

Anand Kore