Rápido: imprimir() frente a println() frente a NSLog()
¿Cuál es la diferencia entre print
y NSLog
cuándo println
debo usar cada uno?
Por ejemplo, en Python, si quisiera imprimir un diccionario, simplemente usaría print myDict
, pero ahora tengo otras 2 opciones. ¿Cómo y cuándo debo usar cada uno?
Algunas diferencias:
print
frente aprintln
:La
print
función imprime mensajes en la consola Xcode al depurar aplicaciones.Es
println
una variación de esto que se eliminó en Swift 2 y ya no se usa. Si ve un código antiguo que utilizaprintln
, ahora puede reemplazarlo de forma segura conprint
.En Swift 1.x,
print
no agregaba caracteres de nueva línea al final de la cadena impresa, mientras queprintln
sí. Pero hoy en día,print
siempre agrega el carácter de nueva línea al final de la cadena y, si no desea que lo haga, proporcione unterminator
parámetro de""
.NSLog
:NSLog
agrega una marca de tiempo y un identificador a la salida, mientras queprint
no lo hará.NSLog
Las declaraciones aparecen tanto en la consola del dispositivo como en la consola del depurador, mientras queprint
solo aparecen en la consola del depurador.NSLog
en iOS 10-13/macOS 10.12-10.x usaprintf
cadenas de formato estilo, por ejemploNSLog("%0.4f", CGFloat.pi)
que producirá:
2017-06-09 11:57:55.642328-0700 MiAplicación[28937:1751492] 3.1416
NSLog
desde iOS 14/macOS 11 puede utilizar la interpolación de cadenas. (Por otra parte, en iOS 14 y macOS 11, generalmente preferiríamosLogger
.NSLog
Consulte el siguiente punto).
Hoy en día, aunque
NSLog
todavía funciona, generalmente usamos "registro unificado" (ver más abajo) en lugar deNSLog
.A partir de iOS 14/macOS 11, tenemos
Logger
una interfaz para el sistema de "registro unificado". Para obtener una introducciónLogger
, consulte WWDC 2020 Explore el inicio de sesión en Swift .Para utilizarlo
Logger
, debes importaros
:import os
Al igual que
NSLog
, el registro unificado enviará mensajes tanto a la consola de depuración de Xcode como a la consola del dispositivo.Crea un
Logger
ylog
un mensaje para él:let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network") logger.log("url = \(url)")
Cuando observa la aplicación a través de la aplicación de consola externa, puede filtrar según
subsystem
ycategory
. Es muy útil diferenciar sus mensajes de depuración de (a) los generados por otros subsistemas en nombre de su aplicación, o (b) mensajes de otras categorías o tipos.Puede especificar diferentes tipos de mensajes de registro, ya sea
.info
,.debug
,.error
,.fault
,.critical
,.notice
,.trace
, etc.:logger.error("web service did not respond \(error.localizedDescription)")
Por lo tanto, si utiliza la aplicación de consola externa, puede elegir ver solo mensajes de ciertas categorías (por ejemplo, mostrar solo mensajes de depuración si elige "Incluir mensajes de depuración" en el menú "Acción" de la consola). Estas configuraciones también dictan muchos detalles sutiles sobre si las cosas se registran en el disco o no. Vea el vídeo de la WWDC para obtener más detalles.
De forma predeterminada, los datos no numéricos se ocultan en los registros. En el ejemplo en el que registró la URL, si la aplicación se invocó desde el propio dispositivo y la estaba mirando desde la aplicación de su consola macOS, verá lo siguiente en la consola macOS:
URL = <privado>
Si estás seguro de que este mensaje no incluirá datos confidenciales del usuario y deseas ver las cadenas en tu consola macOS, tendrías que hacer:
logger.log("url = \(url, privacy: .public)")
Tenga en cuenta que en Xcode 15 y versiones posteriores, ahora puede filtrar el registro por tipo, subsistema, categoría o lo que sea. Personalmente, en proyectos grandes, encuentro útil usar un archivo fuente separado
Logger
para cada archivo fuente, luego puedo filtrar un registro voluminoso a algo más específico (por ejemplo, simplemente registrar mensajes de tipo "error" para una "categoría" particular, etc. ). Para obtener más información, consulte el vídeo de la WWDC 2023 Depuración con registro estructurado .Además, a diferencia de
print
yNSLog
, cuando usaLogger
Xcode 15 o posterior, puede controlhacer clic (o righthacer clic, si ha habilitado el botón derecho del mouse) en un mensaje de registro en la consola de Xcode y elegir "Saltar a la fuente" para saltar. a la línea de código correspondiente.
Antes de iOS 14/macOS 11, se introdujo iOS 10/macOS 10.12
os_log
para el “registro unificado”.Importar
os.log
:import os.log
Debes definir el
subsystem
ycategory
:let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network")
Al usar
os_log
, usaría un patrón de estilo printf en lugar de interpolación de cadenas:os_log("url = %@", log: log, url.absoluteString)
Puede especificar diferentes tipos de mensajes de registro, ya sea
.info
,.debug
,.error
,.fault
(o.default
):os_log("web service did not respond", type: .error)
No puedes usar la interpolación de cadenas cuando usas
os_log
. Por ejemplo conprint
yLogger
lo haces:logger.log("url = \(url)")
Pero con
os_log
, tendrías que hacer:os_log("url = %@", url.absoluteString)
El
os_log
aplica la misma privacidad de datos, pero usted especifica la visibilidad pública en el formateador printf (por ejemplo,%{public}@
en lugar de%@
). Por ejemplo, si quisieras verlo desde un dispositivo externo, tendrías que hacer:os_log("url = %{public}@", url.absoluteString)
También puede utilizar el registro de "Puntos de interés" si desea ver rangos de actividades desde Instrumentos:
let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)
Y comience un rango con:
os_signpost(.begin, log: pointsOfInterest, name: "Network request")
Y terminar con:
os_signpost(.end, log: pointsOfInterest, name: "Network request")
Para obtener más información, consulte https://stackoverflow.com/a/39416673/1271826 .
Como
Logger
,OSLog
puede controlhacer clic (o righthacer clic) en el mensaje y saltar a la línea de código correspondiente en Xcode 15 y versiones posteriores.
En pocas palabras, print
es suficiente para un registro simple con Xcode, pero el registro unificado (ya sea Logger
o os_log
) logra lo mismo pero ofrece capacidades mucho mayores.
El poder del registro unificado se pone de relieve al depurar aplicaciones de iOS que deben probarse fuera de Xcode. Por ejemplo, cuando se prueban procesos de aplicaciones iOS en segundo plano, como la recuperación en segundo plano, estar conectado al depurador de Xcode cambia el ciclo de vida de la aplicación . Por lo tanto, con frecuencia querrás realizar la prueba en un dispositivo físico, ejecutando la aplicación desde el propio dispositivo, no iniciando la aplicación desde el depurador de Xcode. El registro unificado le permite seguir viendo las declaraciones de registro de su dispositivo iOS desde la aplicación de consola macOS.
Si estás usando Swift 2 , ahora solo puedes usar print() para escribir algo en la salida.
Apple ha combinado las funciones println() e print() en una sola.
Actualizado a iOS 9
De forma predeterminada, la función finaliza la línea que imprime agregando un salto de línea.
print("Hello Swift")
terminador
Para imprimir un valor sin un salto de línea después, pase una cadena vacía como terminador
print("Hello Swift", terminator: "")
Separador
Ahora puedes usar el separador para concatenar varios elementos.
print("Hello", "Swift", 2, separator:" ")
Ambos
O podrías combinar el uso de esta manera.
print("Hello", "Swift", 2, separator:" ", terminator:".")
Además, Swift 2 tiene debugPrint()
(y CustomDebugStringConvertible
protocolo).
No olvide debugPrint()
cuál funciona de manera similar print()
pero es más adecuado para la depuración .
Ejemplos:
- Instrumentos de cuerda
print("Hello World!")
se convierteHello World
debugPrint("Hello World!")
se convierte en"Hello World"
(¡Comillas!)
- Rangos
print(1..<6)
se convierte1..<6
debugPrint(1..<6)
se convierteRange(1..<6)
Cualquier clase puede personalizar su representación de cadena de depuración mediante CustomDebugStringConvertible
protocolo.