你可以这样做:
步骤 1: 将您的 NSLog 语句重定向到文件系统中的文本文件。您可以对特定的用户操作执行此操作,或者始终启用它并定期删除它。
第 2 步:拥有一个网络服务,可让您将保存的日志上传到文件系统中。您可以在用户操作时触发此操作,也可以是基于计时器的作业。
第 3 步:上传成功后从文件系统中删除日志。
以下是此类自定义记录器的示例:
#import "MyCustomLogging.h"
#define kMyCustomLoggingFile @"NSLogging.txt"
static NSString *const kMyDeviceLogUploadURL = @"uploadDeviceLogURL";
@interface MyCustomLogging ()
@property (nonatomic, strong) MyRequestHandler *requestHandler;
@property (nonatomic, assign, getter = isNsLogRedirected) BOOL nsLogRedirected;
@property (nonatomic, assign) BOOL shouldStopLogging;
@property (nonatomic, strong) NSString *pathForLogging;
@end
@implementation MyCustomLogging
static int savedStdErr = 0;
static MyCustomLogging *sharedMyCustomLogging = nil;
+ (MyCustomLogging *)sharedMyCustomLogging {
static dispatch_once_t pred = 0;
dispatch_once(&pred, ^{
sharedMyCustomLogging = [[self alloc] init];
});
return sharedMyCustomLogging;
}
#pragma mark -
#pragma mark Start Method
- (void)startLogging {
// Starting the Redirection of the Logs
if (!self.isNsLogRedirected) {
[self nsLogRedirectedToFile];
}
}
#pragma mark -
#pragma mark Stop Method
- (void)stopLogging {
NSLog(@"Stopping the logging");
NSString *aLoggingPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
self.pathForLogging = [aLoggingPath stringByAppendingPathComponent:kMyCustomLoggingFile];
// If file already exists & logging was not redirected then directly upload the logs::A Possible case of app quit/crash without uploading previous logs
if ([self isLogFilePresent] && !self.nsLogRedirected) {
[self uploadLogs];
} else if (self.isNsLogRedirected) { //Check for Successive Stop Notifications
self.shouldStopLogging = YES;
[self restoreNSLog];
} else {
NSDictionary *anUserInfo = @{kMyDeviceLogUplodStatusKey: kMyValueOne};
[[NSNotificationCenter defaultCenter] postNotificationName:kMyDeviceLogsUploadNotification object:nil userInfo:anUserInfo];
}
}
#pragma mark -
#pragma mark Private Method
- (void)nsLogRedirectedToFile {
if (!self.isNsLogRedirected) {
NSLog(@"Redirecting NSLogs to a file.....");
self.nsLogRedirected = YES;
savedStdErr = dup(STDERR_FILENO);
NSString *aLoggingPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
self.pathForLogging = [aLoggingPath stringByAppendingPathComponent:kMyCustomLoggingFile];
NSLog(@"Logging Path: %@", self.pathForLogging);
freopen([self.pathForLogging cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
NSLog(@"NSLog Redirected to a file Succesfully");
[MySessionObject setLoggingOn:YES];
}
}
- (void)restoreNSLog {
if (self.isNsLogRedirected) {
[MySessionObject setLoggingOn:NO];
NSLog(@"NSLog Will be Restored now....");
self.nsLogRedirected = NO;
fflush(stderr);
dup2(savedStdErr, STDERR_FILENO);
close(savedStdErr);
savedStdErr = 0;
}
[self uploadLogs];
NSLog(@"NSLog Restored Successfully");
}
- (void)uploadLogs {
NSLog(@"Now uploading files");
// Disable logging before files are uploading
MySessionObject.enableLogging = NO;
NSError *anError = nil;
NSData *aLogData = [NSData dataWithContentsOfFile:self.pathForLogging options:NSDataReadingUncached error:&anError];
//Converting to String
NSString *aLogString = [[NSString alloc] initWithData:aLogData encoding:NSUTF8StringEncoding];
NSMutableDictionary *aPostBody = [[NSMutableDictionary alloc] initWithCapacity:3];
[aPostBody setValue:aLogString forKey:@"logData"];
[aPostBody setValue:MySessionObject.wifiMACAddress forKey:@"deviceMACAddress"];
[aPostBody setValue:MySessionObject.deviceToken forKey:@"deviceID"];
__weak MyCustomLogging *aBlockSelf = self;
self.requestHandler = [[MyRequestHandler alloc] initWithEndPoint:@"/uploadLogs" body:aPostBody container:nil loadingOverlayTitle:nil successHandler:^(NSDictionary *iResponse) {
if (iResponse) {
//Remove the File From the Path
NSError *aFileError = nil;
BOOL aFileRemoveSuccess = [[NSFileManager defaultManager] removeItemAtPath:self.pathForLogging error:&aFileError];
if (!aFileRemoveSuccess) {
//Tracking the Event
NSString *aDescription = [NSString stringWithFormat:@"Error Code:%ld Error Description:%@", (long)[aFileError code], [aFileError localizedDescription]];
NSLog(@"Error occured while deleting log file:%@", aDescription);
}
// Clearing all
aBlockSelf.pathForLogging = nil;
NSDictionary *anUserInfo = @{kMyDeviceLogUplodStatusKey: kMyValueOne};
[[NSNotificationCenter defaultCenter] postNotificationName:kMyDeviceLogsUploadNotification object:nil userInfo:anUserInfo];
}
} andErrorHandler:^(NSString *iMessage, NSString *iKey, NSInteger iErrorCode, BOOL iIsNetworkError) {
NSDictionary *anUserInfo = @{kMyDeviceLogUplodStatusKey: kMyValueZero};
[[NSNotificationCenter defaultCenter] postNotificationName:kMyDeviceLogsUploadNotification object:nil userInfo:anUserInfo];
}];
[self.requestHandler executeRequest];
}
- (BOOL)isLogFilePresent {
NSFileManager *aFileManager = [[NSFileManager alloc] init];
BOOL aFilePresent = [aFileManager fileExistsAtPath:self.pathForLogging];
return aFilePresent;
}
@end