Difference between println and print in Swift
In the new swift 2, the println has been renamed to print which as an option "terminator" argument.
(udpated 2015-09-16 with the new terminator: "")
var fruits = ["banana","orange","cherry"]
// #1
for f in fruits{
print(f)
}
// #2
for f in fruits{
print("\(f) ", terminator: "")
}
#1 will print
banana
orange
cherry
#2 will print
banana orange cherry
Swift: print() vs println() vs NSLog()
A few differences:
print
vsprintln
:The
print
function prints messages in the Xcode console when debugging apps.The
println
is a variation of this that was removed in Swift 2 and is not used any more. If you see old code that is usingprintln
, you can now safely replace it withprint
.Back in Swift 1.x,
print
did not add newline characters at the end of the printed string, whereasprintln
did. But nowadays,print
always adds the newline character at the end of the string, and if you don't want it to do that, supply aterminator
parameter of""
.NSLog
:NSLog
adds a timestamp and identifier to the output, whereasprint
will not;NSLog
statements appear in both the device’s console and debugger’s console whereasprint
only appears in the debugger console.NSLog
in iOS 10-13/macOS 10.12-10.x usesprintf
-style format strings, e.g.NSLog("%0.4f", CGFloat.pi)
that will produce:
2017-06-09 11:57:55.642328-0700 MyApp[28937:1751492] 3.1416
NSLog
from iOS 14/macOS 11 can use string interpolation. (Then, again, in iOS 14 and macOS 11, we would generally favorLogger
overNSLog
. See next point.)
Nowadays, while
NSLog
still works, we would generally use “unified logging” (see below) rather thanNSLog
.Effective iOS 14/macOS 11, we have
Logger
interface to the “unified logging” system. For an introduction toLogger
, see WWDC 2020 Explore logging in Swift.To use
Logger
, you must importos
:import os
Like
NSLog
, unified logging will output messages to both the Xcode debugging console and the device console, tooCreate a
Logger
andlog
a message to it:let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network")
logger.log("url = \(url)")When you observe the app via the external Console app, you can filter on the basis of the
subsystem
andcategory
. It is very useful to differentiate your debugging messages from (a) those generated by other subsystems on behalf of your app, or (b) messages from other categories or types.You can specify different types of logging messages, either
.info
,.debug
,.error
,.fault
,.critical
,.notice
,.trace
, etc.:logger.error("web service did not respond \(error.localizedDescription)")
So, if using the external Console app, you can choose to only see messages of certain categories (e.g. only show debugging messages if you choose “Include Debug Messages” on the Console “Action” menu). These settings also dictate many subtle issues details about whether things are logged to disk or not. See WWDC video for more details.
By default, non-numeric data is redacted in the logs. In the example where you logged the URL, if the app were invoked from the device itself and you were watching from your macOS Console app, you would see the following in the macOS Console:
url = <private>
If you are confident that this message will not include user confidential data and you wanted to see the strings in your macOS console, you would have to do:
os_log("url = \(url, privacy: .public)")
Prior to iOS 14/macOS 11, iOS 10/macOS 10.12 introduced
os_log
for “unified logging”. For an introduction to unified logging in general, see WWDC 2016 video Unified Logging and Activity Tracing.Import
os.log
:import os.log
You should define the
subsystem
andcategory
:let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network")
When using
os_log
, you would use a printf-style pattern rather than string interpolation:os_log("url = %@", log: log, url.absoluteString)
You can specify different types of logging messages, either
.info
,.debug
,.error
,.fault
(or.default
):os_log("web service did not respond", type: .error)
You cannot use string interpolation when using
os_log
. For example withprint
andLogger
you do:logger.log("url = \(url)")
But with
os_log
, you would have to do:os_log("url = %@", url.absoluteString)
The
os_log
enforces the same data privacy, but you specify the public visibility in the printf formatter (e.g.%{public}@
rather than%@
). E.g., if you wanted to see it from an external device, you'd have to do:os_log("url = %{public}@", url.absoluteString)
You can also use the “Points of Interest” log if you want to watch ranges of activities from Instruments:
let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)
And start a range with:
os_signpost(.begin, log: pointsOfInterest, name: "Network request")
And end it with:
os_signpost(.end, log: pointsOfInterest, name: "Network request")
For more information, see https://stackoverflow.com/a/39416673/1271826.
Bottom line, print
is sufficient for simple logging with Xcode, but unified logging (whether Logger
or os_log
) achieves the same thing but offers far greater capabilities.
The power of unified logging comes into stark relief when debugging iOS apps that have to be tested outside of Xcode. For example, when testing background iOS app processes like background fetch, being connected to the Xcode debugger changes the app lifecycle. So, you frequently will want to test on a physical device, running the app from the device itself, not starting the app from Xcode’s debugger. Unified logging lets you still watch your iOS device log statements from the macOS Console app.
Is there a benefit to use println() to print only Strings?
This depends on which situation you are using println() in.
Playground
Default
In the default playground, both println(someString)
and just someString
on a line by itself will both display the exact same output on the right-hand gutter. In that case they are identical.
Assistant Editor
In a playground you can also open the Assistant editor. You can do this in the menu via View → Assistant Editor → Show Assistant Editor (or the keyboard shortcut ⌥⌘⏎ (main enter key right next to the letters)).
To show a printed string there, you must use println()
. The gutter is more of a quicklook bar, to give you a sense of what is there. The assistant editor has a console, and to print to it you use println()
.
The assistant editor has other uses, like showing previews of views that are being tested, but for this question, that is the major difference between a String
on a single line, and a println()
statement.
Project
In a real project, there are times when you want to test something, like AstroCB was mentioning, you might want to print some text to console. So if you wanted something to print to the console as certain functions or parts of loops were completed, you would use println()
to print something to the console. After running the app, you can see if what you expected to happen did actually do so by only looking at the console.
For debugging, you can use plain Strings
in println()
to see if the program did what you expected, or to find where something was skipped.
Many other situations do make it nicer to just println()
out a formatted string of variable values. For instance, if you expect a certain value for a variable, but it seems to be incorrect when run, you can pepper the method that you are working on that variable with
println("X = \(myXValue)")
to see how it is being affected without having to single-step through the code every time.
print() vs debugPrint() in swift
You use debugPrint when you want more information about what is being printed to the console. The additional information is usually useful for debugging.
print() - Writes the textual representations of the given items into the standard output.
debugPrint() - Writes the textual representations of the given items most suitable for debugging into the standard output.
Basically debugPrint adds additional information that is useful for debugging like type information etc.
An example:
print(1...5)
// Prints "1...5"
debugPrint(1...5)
// Prints "CountableClosedRange(1...5)"
Difference between Printable and DebugPrintable in Swift
In Xcode 6 Beta (Version 6.2 (6C101)) I find that both println and debugPrintln use description if-and-only-if the class descends from NSObject. I don't see that either uses debugDescription at all but when run in a Playground debugPrintln outputs only to the Console and doesn't appear in the playground itself.
import Foundation
class Tdesc: NSObject, Printable, DebugPrintable {
override var description: String {return "A description"}
override var debugDescription: String {return "A debugDescription"}
}
class Xdesc: Printable, DebugPrintable {
var description: String {return "A description"}
var debugDescription: String {return "A debugDescription"}
}
let t = Tdesc()
let x = Xdesc()
t.description
let z: String = "x\(t)"
println(t) // Displays "A description" in the Playground and Console
debugPrintln(t) // Displays nothing in the Playground but "A description" in the Console
x.description
let y: String = "x\(x)"
println(x) // Displays "__lldb_expr_405.Xdesc" in the Playground and Console
debugPrintln(x)
How do you do println() in swift 2
it's print("hello world")
. it's changed in swift 2.0 and you need to see Apple's website. put print()
instead of println()
Text direction with print or println in Swift for mixed text
It looks like I found the answer. Adding "\u{200E}", the Left to Right Mark before the character resolves the issue.
More here: http://en.wikipedia.org/wiki/Left-to-right_mark
Swift: println value to pass
T
means println
accepts a parameter of any type.
float
, string
, char
, int
etc will be converted to a string.
Objects (like NSData
or UIImage
) will have their description
method called, and return that. NSData
will give you a hexadecimal representation of the data, while UIImage
prints some details about the image (width, height, etc).
If you want to print out classes you've defined yourself, you should consider implementing a description method. Otherwise you'll just get the class name and memory address.
Also, you can embed an object of any type in a string and combine that with println():
let a = 7
let b = 6
let c = a * b
println("\(a) times \(b) is \(c)")
// 7 times 6 is 42
Related Topics
Delete All Characters After a Certain Character from a String in Swift
How to Repeat Animation (Using Uiviewpropertyanimator) Certain Number of Times
Can You Give Uistackview Borders
Difference Between Awakefromnib() and Viewdidload() in Swift
iOS Tabbar Item Title Issue in iOS13
How to Animate Transition Between Views in Swiftui
Firebase Query Containing Value
Strange Error Nw_Protocol_Get_Quic_Image_Block_Invoke Dlopen Libquic Failed
Swift: How to Access in Appdelegate Variable from the View Controller
Sum Values of Properties Inside Array of Custom Objects Using Reduce
Insertion-Order Dictionary (Like Java's Linkedhashmap) in Swift
Swiftui .Rotationeffect() Framing and Offsetting
Swift: Popover Dismiss Callback