目录
IOS沙盒机制和文件结构
沙盒机制:App只能访问对应的文件夹及相关资源,App之间无法共享文件等资源
Document:可以进行备份和恢复,体积较大,一般存档用户数据
Library:开发者最常使用的文件夹,可以自定义子文件夹
Preference:用户偏好设置,NSUserDefault,支持备份
Cache:不需要缓存的,体积较大,一般的删除缓存操作
......
SystemData:系统文件
tmp:临时文件不会备份,启动时可能会被删除
IOS获取沙盒地址:NSPathUtilities
-(void) _getSandBoxPath{
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"");
}
IOS文件管理
NSFileManager
1.单例,提供App内文件&文件夹管理功能
2.创建、删除、查询、移动、复制文件
3.读取文件内容&属性
4.通过NSURL或者NSString作为Path
NSFileManagerDelegate:提供移动、复制、删除等操作的具体自定义实现
NSFileHandle
1.读取文件&写文件
2.读取指定长度&在指定位置追加/截断
3.截断&立即刷新
4.常用语追加数据
// 创建
+ (nullable instancetype)fileHandleForReadingAtPath:(NSString *)path;
+ (nullable instancetype)fileHandleForWritingAtPath:(NSString *)path;
+ (nullable instancetype)fileHandleForUpdatingAtPath:(NSString *)path;
// 读&写
- (NSData *)readDataOfLength:(NSInteger)length;
- (void)seekToFileOffset:(unsigned long long)offset;
- (void)writeData:(NSData *)data;
简单实现创建、查询、删除文件及追加内容
-(void) _getSandBoxPath{
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [pathArray firstObject];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dataPath = [cachePath stringByAppendingPathComponent:@"GSCData"]; // cache文件夹下创建GSCData子文件夹
NSError *createError;
[fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&createError];
NSString *listDataPath = [dataPath stringByAppendingPathComponent:@"list"]; // 创建文件
NSData *listData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding];
[fileManager createFileAtPath:listDataPath contents:listData attributes:nil];
//查询文件
BOOL fileExist = [fileManager fileExistsAtPath:listDataPath];
// //删除文件
// if(fileExist){
// [fileManager removeItemAtPath:listDataPath error:nil];
// }
//
// 追加文件内容
NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:listDataPath];
[fileHandle seekToEndOfFile];
[fileHandle writeData:[@"def" dataUsingEncoding:NSUTF8StringEncoding]];
[fileHandle synchronizeFile];
[fileHandle closeFile];
}
IOS中的序列化
NSCoder
1.归档(序列化)&解归档(反序列化)
2.提供简单的函数,在Object和二进制数据见进行转换
3.抽象类 具体功能需要子类实现
// encode
- (void)encodeObject:(nullable id)object forKey:(NSString *)key;
- (void)encodeBool:(BOOL)value forKey:(NSString *)key;
- (void)encodeInt:(int)value forKey:(NSString *)key;
- (void)encodeInt32:(int32_t)value forKey:(NSString *)key;
- (void)encodeInt64:(int64_t)value forKey:(NSString *)key;
- (void)encodeFloat:(float)value forKey(NSString *)key;
- (void)encodeDouble:(double)value forKey(NSString *)key;
//decode
- (nullable id)decodeObjectForKey:(NSString*)key;
- (BOOL)decodeBoolForKey:(NSString *)key;
- (int)decodeIntForKey:(NSString *)key;
- (int32_t)decodeInt32ForKey:(NSString *)key;
- (int64_t)decodeInt64ForKey:(NSString *)key;
- (float)decodeFloatForKey:(NSString *)key;
- (double)decodeDoubleForKey:(NSString *)key;
为了向前向后兼容,不依赖顺心,所以需要将非基本数据对应到key存储
NSKeyedArchiver
1.NScoder的子类
2.提供简单的函数,在Object和二进制数据之间进行转换
3.提供基本的delegate
4.需要Object自己处理Key-Value的对应关系
NSCoding
对于Objecy等序列化&反序列化协议
·NSArray&NSDictionary等类型系统已经实现协议
·NSSecureCoding
1.解决文件替换攻击
2.序列化时规定Class
简单实现数据的序列化与反序列化
//实现NSSecureCoding
//
// GSCListItem.h
// GSCApp1
//
// Created by gsc on 2024/5/23.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/*
列表结构化属性
*/
@interface GSCListItem : NSObject <NSSecureCoding>
@property (nonatomic, copy, readwrite) NSString * category;
//@property (nonatomic, copy, readwrite) NSString * isContent;
@property (nonatomic, copy, readwrite) NSString * picUrl;
@property (nonatomic, copy, readwrite) NSString * uniquekey;
@property (nonatomic, copy, readwrite) NSString * title;
@property (nonatomic, copy, readwrite) NSString * date;
@property (nonatomic, copy, readwrite) NSString * authorName;
@property (nonatomic, copy, readwrite) NSString * articleUrl;
-(void) configWithDictionary:(NSDictionary *) dictionary;
@end
NS_ASSUME_NONNULL_END
//
// GSCListItem.m
// GSCApp1
//
// Created by gsc on 2024/5/23.
//
#import "GSCListItem.h"
@implementation GSCListItem
#pragma mark - NSSecureCoding
-(nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if(self){
self.category = [aDecoder decodeObjectForKey:@"category"];
self.picUrl = [aDecoder decodeObjectForKey:@"thumbnail_pic_s"];
self.uniquekey = [aDecoder decodeObjectForKey:@"uniquekey"];
self.title = [aDecoder decodeObjectForKey:@"title"];
self.date = [aDecoder decodeObjectForKey:@"date"];
self.authorName = [aDecoder decodeObjectForKey:@"author_name"];
self.articleUrl = [aDecoder decodeObjectForKey:@"url"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.category forKey:@"category"];
[aCoder encodeObject:self.picUrl forKey:@"thumbnail_pic_s"];
[aCoder encodeObject:self.uniquekey forKey:@"uniquekey"];
[aCoder encodeObject:self.title forKey:@"title"];
[aCoder encodeObject:self.date forKey:@"date"];
[aCoder encodeObject:self.authorName forKey:@"author_name"];
[aCoder encodeObject:self.articleUrl forKey:@"url"];
}
#pragma mark - NSSecureCoding
+(BOOL)supportsSecureCoding{
return YES;
}
#pragma mark - public method#pragma mark - NSSecureCoding
- (void)configWithDictionary:(NSDictionary *)dictionary {
self.category = [dictionary objectForKey:@"category"];
self.picUrl = [dictionary objectForKey:@"thumbnail_pic_s"];
self.uniquekey = [dictionary objectForKey:@"uniquekey"];
self.title = [dictionary objectForKey:@"title"];
self.date = [dictionary objectForKey:@"date"];
self.authorName = [dictionary objectForKey:@"author_name"];
self.articleUrl = [dictionary objectForKey:@"url"];
}
@end
//
// GSCListLoader.m
// GSCApp1
//
// Created by gsc on 2024/5/20.
//
#import "AFNetworking/AFNetworking.h"
#import "GSCListItem.h"
#import "GSCListLoader.h"
@implementation GSCListLoader
- (void)loadListDataWithFinishBlock:(GSCListLoaderFinishBlock)finishBlock {
NSString *urlString = @"http://v.juhe.cn/toutiao/index?type=top&key=97ad001bfcc2082e2eeaf798bad3d54e";
NSURL *listURL = [NSURL URLWithString:urlString];
NSURLSession *session = [NSURLSession sharedSession];
__weak typeof(self) weakself = self;
NSURLSessionTask *dataTask = [session dataTaskWithURL:listURL
completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
__strong typeof(weakself) strongSelf = weakself;
NSError *jsonError;
id jsonObj = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&jsonError];
NSArray *dataArray = [((NSDictionary *)[((NSDictionary *)jsonObj) objectForKey:@"result"]) objectForKey:@"data"];
NSMutableArray *listItemArray = @[].mutableCopy;
for (NSDictionary *info in dataArray) {
GSCListItem *listItem = [[GSCListItem alloc] init];
[listItem configWithDictionary:info];
[listItemArray addObject:listItem];
}
[strongSelf _archiveListDataWithArray:listItemArray.copy];
dispatch_async(dispatch_get_main_queue(), ^{
if (finishBlock) {
finishBlock(error == nil, listItemArray);
}
});
}];
[dataTask resume];
}
-(void) _archiveListDataWithArray:(NSArray<GSCListItem *> *)array{
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [pathArray firstObject];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dataPath = [cachePath stringByAppendingPathComponent:@"GSCData"]; // cache文件夹下创建GSCData子文件夹
NSError *createError;
[fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&createError];
NSString *listDataPath = [dataPath stringByAppendingPathComponent:@"list"]; // 创建文件
// NSData *listData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding];
// 数据序列化
NSData *listData = [NSKeyedArchiver archivedDataWithRootObject:array requiringSecureCoding:YES error:nil];
[fileManager createFileAtPath:listDataPath contents:listData attributes:nil];
NSData *readListData = [fileManager contentsAtPath:listDataPath];
// 数据反序列化
id unarchiveObj = [NSKeyedUnarchiver unarchivedObjectOfClasses: [NSSet setWithObjects:[NSArray class], [GSCListItem class], nil]
fromData: readListData error:nil];
}
@end
开源存储方案
NSUserDefault
提供简单的key-value存储
1.单例,存取轻量级的数据 2.支持基本的数据类型
3.一般用于用户的偏好设置 4.保存Integer Float Double Bool
5.升级安装后还可以继续使用 6.保存NSArray NSData NSString NSDictionary
7.文件存储在/Library/Preference下 7.复杂Model需要转化成NSData
-(void) _archiveListDataWithArray:(NSArray<GSCListItem *> *)array{
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [pathArray firstObject];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dataPath = [cachePath stringByAppendingPathComponent:@"GSCData"]; // cache文件夹下创建GSCData子文件夹
NSError *createError;
[fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&createError];
NSString *listDataPath = [dataPath stringByAppendingPathComponent:@"list"]; // 创建文件
// NSData *listData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding];
// 数据序列化
NSData *listData = [NSKeyedArchiver archivedDataWithRootObject:array requiringSecureCoding:YES error:nil];
[fileManager createFileAtPath:listDataPath contents:listData attributes:nil];
NSData *readListData = [fileManager contentsAtPath:listDataPath];
// 数据反序列化
id unarchiveObj = [NSKeyedUnarchiver unarchivedObjectOfClasses: [NSSet setWithObjects:[NSArray class], [GSCListItem class], nil]
fromData: readListData error:nil];
[[NSUserDefaults standardUserDefaults] setObject:listData forKey:@"listData"];
NSData *testListData = [[NSUserDefaults standardUserDefaults] dataForKey:@"listData"];
id unarchiveObjTest = [NSKeyedUnarchiver unarchivedObjectOfClasses: [NSSet setWithObjects:[NSArray class], [GSCListItem class], nil]
fromData: testListData error:nil];
}
开源框架
系统级存储:NSUserData、keychain、通过NSKeyedArchiver归档后存文件、数据库CoreData
key-value类型:LevelDB/MMKV/Realm
关系数据库类型:SQLite/FMDB/WCDB
标签:nil,self,IOS,学习,NSString,void,key,序列化,日记 From: https://blog.csdn.net/gsc711/article/details/139181058