iOS 10 / Xcode 8의 장치에서 NSLog가 잘리는 것처럼 보입니까? 왜?
콘솔 출력이 Xcode 8 / iOS 10에서 불완전한 것으로 표시되는 이유는 무엇입니까?
임시 해결책은 단지 모든 재정 NSLOG
에 printf
글로벌 헤더 파일에.
#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
iOS 10 및 Xcode 8에서 Apple은 오래된 ASL
(Apple System Log)에서 Unified logging
. NSLog
실제로 호출은 새 os_log
API에 위임됩니다 . (출처 : https://developer.apple.com/reference/os/logging ) :
중대한
통합 로깅은 iOS 10.0 이상, macOS 10.12 이상, tvOS 10.0 이상 및 watchOS 3.0 이상에서 사용할 수 있으며 ASL (Apple System Logger) 및 Syslog API를 대체합니다. 역사적으로 로그 메시지는 /etc/system.log와 같은 디스크의 특정 위치에 기록되었습니다. 통합 로깅 시스템은 텍스트 기반 로그 파일에 쓰는 대신 메모리와 데이터 저장소에 메시지를 저장합니다.
과
중대한
시스템의 최대 메시지 길이보다 큰 로그 메시지 행은 로깅 시스템에 의해 저장 될 때 잘립니다. 로그 명령 줄 도구를 사용하여 실시간 활동 스트림을 볼 때 완전한 메시지가 표시됩니다. 그러나 스트리밍 로그 데이터는 비용이 많이 드는 작업입니다.
@Hot_Leaks (출처 :)에서 언급 한 바와 같이 "시스템의 최대 메시지 길이"제한은 SDK의 헤더에서 형식화 된 변수에 대해 1024 자로 표시됩니다 <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__)
버퍼 크기 제한이으로 하드 코딩 된 것 같기 때문에 libsystem_trace.dylib
주위에 방법이 없지만 형식이 지정된 변수 ( %@
) 대신 문자열 리터럴을 인쇄 하거나 형식이 지정된 문자열 변수를 <1024 문자열로 분할합니다.
printf
디버거 (Xcode)가 프로세스의 출력 / 오류 스트림을 표시하므로 디버깅 중에 작동하지만 장치 로그 자체에는 전송되지 않습니다. 즉, xfdai의 솔루션은 macOS의 Console
앱 과 같은 다른 로그 응용 프로그램을 사용 하거나 디버깅되지 않은 응용 프로그램 (예 : 고객의 장치에서 실행되는 AppStore 응용 프로그램)에서 문제 가 발생할 때 도움이되지 않습니다 .
xfdai의 답변을 배포 된 애플리케이션으로 확장
배포 된 애플리케이션 / 디버그가 아닌 빌드에서는 NSLog
s 또는 printf
s 를 볼 수있는 방법이 없습니다 .
장치 로그 (Xcode-> Window-> Devices, mac의 콘솔 앱 또는 deviceconsole 과 같은 타사 유틸리티를 사용하여 액세스 할 수 있음)에 직접 메시지를 인쇄하는 유일한 방법 은 os_log
API ( ASL
iOS 10 이후 사용 된 후속 유틸리티 )를 호출 하는 것입니다. ).
다음 은 iOS 10 NSLog
에서 호출로 재정의하는 데 사용하는 전역 헤더 파일입니다 _os_log_internal
.
#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 */
iOS 10 전용 "기능"입니다. 대신 사용 :
printf("%s", [logString UTF8String]);
iOS 10 :
printf()
Xcode의 콘솔 내에서 작동하지만 장치의 콘솔 로그에서는 작동하지 않습니다.NSLog
두 곳 모두에서 잘립니다.
지금 제가하고있는 것은 NSLog
문자열을 줄로 나누고 각 줄을 개별적으로 로깅하는 것입니다.
- (void) logString: (NSString *) string
{
for (NSString *line in [string componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]])
{
NSLog(@"%@", line);
}
}
이것은 콘솔에서 작동하지만 읽기가 쉽지 않습니다.
이 방법을 사용할 수 있습니다. 800 자마다 분할합니다. 또는 설정할 수 있습니다. NSLOG 나는 1000 자마다 자른다 고 생각합니다. 문자열이 800 미만이면 간단한 NSLog를 사용합니다. 이것은 Json 긴 문자열에 유용하며 콘솔을 사용합니다. printf는 콘솔이 아닌 Xcode 디버그 창을 사용합니다.
-(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);
}
}
'program tip' 카테고리의 다른 글
iOS7의 UIActivityViewController에서 표시 될 때 메일 작성기에서 보내기 및 취소 단추의 텍스트 색상을 설정할 수 없습니다. (0) | 2020.11.11 |
---|---|
Promise에서 여러 값을 올바르게 반환하는 방법은 무엇입니까? (0) | 2020.11.11 |
응용 프로그램이 화면 방향 변경을 무시하도록하는 방법은 무엇입니까? (0) | 2020.11.11 |
Android의 여러 MIME 유형 (0) | 2020.11.11 |
어떤 Linux IPC 기술을 사용해야합니까? (0) | 2020.11.11 |