先把需求發一下:
• 客戶端以日誌的形式,記錄用戶的基本信息、使用環境、使用行爲等數據。
1
上報策略
• 程序進入後臺模式時,立即上傳緩存的日誌文件
• 按照時間,以每小時的頻率進行數據上報
• 日誌文件小於30KB時,不進行上報
• 上報成功後,清除已上傳成功的日誌文件
• 特殊上報策略——客戶端啓動觸發的事件,實時上報
這裏只介紹怎麼對文件進行操作。
因爲全局任何時刻都有可能會寫入日誌,並且有可能會存儲好幾個用戶的日誌。所以我用了單例寫,並且有個屬性記錄下了當前操作的文件路徑。那麼先來寫個單例。
@property (nonatomic,strong)NSString * filePath;//當前操作的文件的路徑
@property (nonatomic,strong)dispatch_queue_t concurrentWriteFileQueue;//自己創建的一個線程
- (instancetype) shareInstance{
static dispatch_once_t onceToken;
static UserInfoCollection *UIC = nil;
//確保創建單例只被執行一次。
dispatch_once(&onceToken, ^{
UIC = [UserInfoCollection new];
//自己建立一個線程
UIC.concurrentWriteFileQueue = dispatch_queue_create("人家是寫文件的線程自定義隊列", DISPATCH_QUEUE_CONCURRENT);
});
return UIC;
}
創建文件。
(void)createFileWithUID:(NSString*)UID{
// 文件存儲的路徑,
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentDirectory = [paths objectAtIndex:0];
NSLog(@"%@",documentDirectory);
NSFileManager *manager = [NSFileManager defaultManager];
// 路徑下的所有文件名
NSArray *filePathArr = [manager contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/",documentDirectory] error:nil];
NSLog(@"arr = %@",filePathArr);
// 用UID 匹配文件 如果已經有了某個用戶的日誌,那麼就返回這個用戶的文件路徑,不創建新的。
for (NSString * file in filePathArr) {
if ([file rangeOfString:[NSString stringWithFormat:@"%@_",UID]].location != NSNotFound) {
// 已經有了文件,
//UIC.filePath 當前操作的文件的路徑
UIC.filePath = [NSString stringWithFormat:@"%@/%@",documentDirectory,file];
return;
}
}
//首次創建文件名
NSString *testPath = [NSString stringWithFormat:@"%@/%@_%@_%@%@",documentDirectory,UID,@"設備號",@"時間戳",@".txt"];
BOOL ifFileExist = [manager fileExistsAtPath:testPath];
BOOL success = NO;
if (ifFileExist) {
NSLog(@"文件已經存在");
UIC.filePath = testPath;
}else{
NSLog(@"文件不存在");
success = [manager createFileAtPath:testPath contents:nil attributes:nil];
}
if (!success) {
NSLog(@"創建文件不成功");
UIC.filePath = nil;
// 錯誤判斷+++
}else{
NSLog(@"創建文件成功");
UIC.filePath = testPath;
}
}
文件寫入
- (void)writeMessageToFileWithJsonStr:(NSDictionary*)dic{
if (!UIC.filePath) {
NSLog(@"文件路徑錯誤,寫不進去");
return;
}
NSFileHandle *file = [NSFileHandle fileHandleForUpdatingAtPath:UIC.filePath];
// 字典轉JSON
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *jsonStr = [json stringByAppendingString:@",\n"];
// 在文件的末尾添加內容。如果想在開始寫 [file seekToFileOffset:0];
[file seekToEndOfFile];
NSData *strData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
[file writeData:strData ];
}
計算文件的大小
//文件大小
- (float)fileSize{
NSFileManager *manager = [NSFileManager defaultManager];
return [[manager attributesOfItemAtPath:UIC.filePath error:nil] fileSize]/(1024.0);//這裏返回的單位是KB
}
刪除文件
- (void)deleteUserInfoFile{
dispatch_barrier_async(UIC.concurrentWriteFileQueue, ^{
NSFileManager *manager = [NSFileManager defaultManager];
BOOL deleSuccess = [manager removeItemAtPath:UIC.filePath error:nil];
if (deleSuccess) {
NSLog(@"刪除文件成功");
}else{
NSLog(@"刪除文件不成功");
}
});
}
創建文件並寫入一些信息
- (void)userInfoWithUID:(NSString*)UID{
//添加寫操作到自定義隊列,當稍後執行時,這將是隊列中唯一執行的條目。這個Block永遠不會同時和其他Block一起在隊列中執行
dispatch_barrier_async(UIC.concurrentWriteFileQueue, ^{
[UIC createFileWithUID:UID];
NSDictionary *dic = @{
@"u":@{
@"uid":UID,//
@"device":@"設備號",
@"brand":@"設備信息",
@"os":@"設備操作系統信息",
@"tag":@"客戶端發佈渠道",
@"clienttype":@"iPhone",
@"version":@"x.x.xxxx"
}
};
[self writeMessageToFileWithJsonStr:dic];
});
}
自定義一個線程隊列,比較方便調試 。
最後是寫好的文件。
————————————————
版權聲明:本文爲CSDN博主「淡暗雲之遙」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/squallmouse/article/details/52024324