puedo para como actualizar ios objective-c xcode ios10 xcode8

para - NSLog en dispositivos en iOS 10/Xcode 8 parece truncarse? ¿Por qué?



ios 12 (5)

En iOS 10 y Xcode 8, Apple cambió del antiguo ASL (registro del sistema de Apple) a un nuevo sistema de registro llamado Unified logging . NSLog llamadas de NSLog se NSLog a las nuevas API de os_log . (fuente: https://developer.apple.com/reference/os/logging ):

Importante

El registro unificado está disponible en iOS 10.0 y posterior, macOS 10.12 y posterior, tvOS 10.0 y posterior, y watchOS 3.0 y posterior, y reemplaza ASL (Apple System Logger) y las API de Syslog. Históricamente, los mensajes de registro se escribieron en ubicaciones específicas del disco, como /etc/system.log. El sistema de registro unificado almacena mensajes en la memoria y en un almacén de datos, en lugar de escribir en archivos de registro basados ​​en texto.

Y

Importante

Las líneas de mensajes de registro mayores que la longitud máxima del mensaje del sistema se truncan cuando el sistema de registro las almacena. Los mensajes completos son visibles cuando se utiliza la herramienta de línea de comandos de registro para ver una transmisión de actividad en vivo. Sin embargo, tenga en cuenta que la transmisión de datos de registro es una actividad costosa.

La limitación de "longitud máxima del mensaje del sistema" se revela en el encabezado del SDK como 1024 caracteres para variables formateadas, como lo señala @Hot_Leaks (fuente: <os/log.h> ):

/*! * @function os_log * * ... * * There is a physical cap of 1024 bytes per log line for dynamic content, * such as %s and %@, that can be written to the persistence store. * All content exceeding the limit will be truncated before it is * written to disk. * * ... * */ #define os_log(log, format, ...) os_log_with_type(log, OS_LOG_TYPE_DEFAULT, format, ##__VA_ARGS__)

Dado que la limitación del tamaño del búfer parece estar codificada en libsystem_trace.dylib , no veo una forma de libsystem_trace.dylib sino imprimir un literal de cadena en lugar de una variable formateada ( %@ ), o dividir las variables de cadena formateadas a <1024 instrumentos de cuerda.

printf funcionará durante la depuración, ya que el depurador (Xcode) muestra las secuencias de salida / error del proceso, pero no se enviará al registro del dispositivo en sí. Esto significa que la solución de xfdai no lo ayudará cuando use otras aplicaciones de registro, como la aplicación de Console de macOS, o cuando surjan problemas en aplicaciones no depuradas (como la aplicación AppStore que se ejecuta en el dispositivo del cliente).

Extender la respuesta de xfdai a las aplicaciones implementadas

En las aplicaciones implementadas / compilaciones sin depuración, no hay forma de ver NSLog s o printf s.

La única forma de tener mensajes impresos directamente en el registro del dispositivo (al que se puede acceder usando Xcode -> Ventana -> Dispositivos, la Aplicación de consola de Mac o utilidades de terceros como deviceconsole ) es llamar a os_log API os_log (que es el sucesor de ASL utilizado desde iOS 10).

Aquí hay un archivo de encabezado global que estoy usando para redefinir NSLog como una llamada a _os_log_internal en iOS 10:

#ifndef PrefixHeader_pch #define PrefixHeader_pch #ifdef __OBJC__ #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #endif #import <os/object.h> #import <os/activity.h> /* * System Versioning Preprocessor Macros */ #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) // os_log is only supported when compiling with Xcode 8. // Check if iOS version > 10 and the _os_log_internal symbol exists, // load it dynamically and call it. // Definitions extracted from #import <os/log.h> #if OS_OBJECT_SWIFT3 OS_OBJECT_DECL_SWIFT(os_log); #elif OS_OBJECT_USE_OBJC OS_OBJECT_DECL(os_log); #else typedef struct os_log_s *os_log_t; #endif /* OS_OBJECT_USE_OBJC */ extern struct os_log_s _os_log_default; extern __attribute__((weak)) void _os_log_internal(void *dso, os_log_t log, int type, const char *message, ...); // In iOS 10 NSLog only shows in device log when debugging from Xcode: #define NSLog(FORMAT, ...) / if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {/ void(*ptr_os_log_internal)(void *, __strong os_log_t, int, const char *, ...) = _os_log_internal;/ if (ptr_os_log_internal != NULL) {/ _Pragma("clang diagnostic push")/ _Pragma("clang diagnostic error /"-Wformat/"")/ _os_log_internal(&__dso_handle, OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_default), 0x00, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);/ _Pragma("clang diagnostic pop")/ } else {/ NSLog(FORMAT, ##__VA_ARGS__);/ }/ } else {/ NSLog(FORMAT, ##__VA_ARGS__);/ } #endif /* PrefixHeader_pch */

¿Por qué la salida de la consola se muestra incompleta en Xcode 8 / iOS 10?


En iOS 10:

  1. printf() funciona dentro de la consola de Xcode pero no funciona en el registro de la consola del dispositivo.
  2. NSLog trunca en ambos lugares.

Lo que estoy haciendo por ahora es dividir mis cadenas NSLog en líneas y registrar cada línea individualmente.

- (void) logString: (NSString *) string { for (NSString *line in [string componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]]) { NSLog(@"%@", line); } }

Esto funciona en la consola, pero no es fácil de leer.


Es una "característica" solo para iOS 10. Use esto en su lugar:

printf("%s", [logString UTF8String]);


Puedes usar este método. Dividir cada 800 caracteres. O se puede configurar. NSLOG creo que truncar cada 1000 caracteres. Si la cadena es menor que 800, usará un NSLog simple. Esto es útil para cadenas largas de Json y utiliza la consola. printf usa la ventana de depuración de Xcode, no la consola.

-(void) JSLog:(NSString*)logString{ int stepLog = 800; NSInteger strLen = [@([logString length]) integerValue]; NSInteger countInt = strLen / stepLog; if (strLen > stepLog) { for (int i=1; i <= countInt; i++) { NSString *character = [logString substringWithRange:NSMakeRange((i*stepLog)-stepLog, stepLog)]; NSLog(@"%@", character); } NSString *character = [logString substringWithRange:NSMakeRange((countInt*stepLog), strLen-(countInt*stepLog))]; NSLog(@"%@", character); } else { NSLog(@"%@", logString); } }


Una solución temporal, simplemente redefina todos los NSLOG para NSLOG en un archivo de encabezado global.

#define NSLog(FORMAT, ...) printf("%s/n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);