美文网首页iOS开发之笔记摘录
网络 模型转换 存储---iOS笔记摘录

网络 模型转换 存储---iOS笔记摘录

作者: 平安喜乐698 | 来源:发表于2017-09-13 15:19 被阅读8112次
    目录
        1. 网络
           1.1 监测网络状态 
           1.2 AFNetworking
           1.3 NSURLSession
           1.4 NSURLConnection 
        2. 模型转换
           2.1 JSONModel
           2.2 MJExtension
        3. 存储
           3.1 NSUserDefaults
           3.2 NSCoding
           3.3 sqlite
           3.4 FMDB
           3.5 CoreData
           3.6 读写文件
        4. 其他相关
           4.1 SDWebImage 第三方加载网络图片
    
    1. 网络
    注意:
    
      1.App如果需要进行网络操作,则要在info.plist文件中添加权限:
    
            <key>NSAppTransportSecurity</key>
            <dict>
                <key>NSAllowsArbitraryLoads</key>
                <true/>
            </dict>
    
    菊花
        // 是否打开菊花(状态栏上:用来提示用户正在请求网络)
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:true];
    
    data<->str
        // data->str
        NSString *str=[[NSString alloc]initWithData:[NSData new] encoding:NSUTF8StringEncoding];
        // str->data
        NSData *data=[@"" dataUsingEncoding:NSUTF8StringEncoding];
    
    中文
        对中文编码(url中有中文)
        string.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLFragmentAllowedCharacterSet())! 
        对中文解码       
        paraStr.stringByRemovingPercentEncoding
    
    Charles(抓包)
        1. 下载charles
        2. 连上同一Wifi,手机设置wifi为手动:服务器(mac终端:ifconfig en0 找到地址) 端口:8888(默认:charles的Proxy中设置的)
        3. OK
    

    概念

            上传数据:保存
            获取数据:显示
            中间数据传输格式:JSON等
    

    URL

    URL(统一资源定位符)
        协议://域名/具体路径?参数1=值&参数2=值
        用于规范获取资源的地址   
    
        常用协议
            http:   // 超文本传输协议(远程网络资源)
            file:   // 本地计算机上的资源
            ftp:    // 共享主机的文件资源
    
    url需满足
        1.必须是ASCII 字符(用%+两位十六进制数来替换非 ASCII 字符,比如中文就要进行处理)
        2.不能包含空格
    
    HTTP
        超文本传输协议(应用层协议),分为请求报文和响应报文。请求报文包括请求头和数据,响应报文包括响应头和数据。
        基于TCP,短连接,发送一次请求后就断开。
    
    Socket
        用于即时更新数据的应用(游戏)
        基于TCP,长连接,保持连接。
    
    物理层、数据链路层、网络层、运输层、应用层
    传输层协议
        TCP(传输控制层协议):面向连接(3次握手)、可靠、点对点
        UDP(用户数据报协议):非连接、不可靠、点对多点(用于视频)
    

    客户端与服务端交互方式

    客户端与服务端交互(2种方式):
          pull:客户端向服务端请求数据,服务端从数据库中获取数据返回给客户端
          push:远程推送
    
    
    pull的请求方式
        增:PUT 删:DELETE 改:POST 查:GET
        最常用:GET和POST,GET传输不安全且对传入参数的长度有限制。
            GET
            参数会拼接在地址后(?参名=参值&参名=参值),不安全。有长度限制。
            POST
            相对安全,没有长度限制。    
    
    同步请求和异步请求的区别:
        同步请求会在获取到后台数据后继续往下执行,会造成UI卡顿。(基本不用)
        异步请求会创建线程进行请求。
    

    JSON

    JSON最外层是字典或数组
                字典(即对象) { }         
                  键类型可以是:字符串型
                  值类型可以是:字典、数组、整型、浮点型、布尔型、字符串型、null
                数组        [ ]
        
    注意:
        NSArray、NSDictionary中只能存放类类型的对象,所以
                    用 NSNumber(NSValue的子类) 封装Int、Float、Double、Bool
                    用 NSNull 封装nil
    例:
     {
        "k0":null,
        "k1":"sb”,
        "k2":123,
        "k3":true,
        "k4”:[1,2,3],
        "k5":{
            "key5":55
        },
    }
    

    XML(过时, 现只用于存储,不用于传输)

    用来存储和传递数据(优点:可读性强,缺点:太冗余)
        文档由节点(开始标签和结束标签组成)构成
    
    
    例:
    <?xml version="1.0" encoding="UTF-8">
    <books>                             根节点
        <book id="0">                   id是属性节点
            <name>book1</name>          name是元素节点
            <price>12</price>
        </book>
    </books>
    
    
    
    使用(2方式):
    —————————方式一
    第一步:
        1. 导入Data文件,建立桥接文件  :   #import "GDataXMLNode.h"
        2. Build Phase  |  Link Binary With Libraries  添加libxml2.tbd
        3. Build Phase  |  Compile Source   .m文件后双击 +  -fno-objc-arc
        4. BuildSettings | header Search Path  +  /usr/include/libxml2
    第二步:
            let path=NSBundle.mainBundle().pathForResource("xml", ofType: "txt")
            let data=NSData.init(contentsOfFile: path!)
            let doc=try! GDataXMLDocument.init(data: data, options: 0)      // 解析数据
            
            let rootE=doc.rootElement()     // 获取根节点
            print(rootE.XMLString())        // 打印节点
            
            // 获取节点的内容(根据节点名)
            let booksArr=rootE.elementsForName("books") as! [GDataXMLElement]       // 获取元素节点(返回数组)
            let booksEl=booksArr[0]
            
            let bookArr=booksEl.elementsForName("book") as! [GDataXMLElement]
            for bookEl in bookArr{
                let name=(bookEl.elementsForName("name")[0]) as! GDataXMLElement    // 
                let attName=bookEl.attributes()[0] as! GDataXMLNode                 // 获取属性节点(返回数组)
                print(name.stringValue())                                           // 节点值      name.name()节点名
            }
    —————————方式二
        XPath 使用路径表达式获取节点
        /   从根节点获取
        //  查询和名称相同的节点(不考虑位置)
        .   获取当前节点
        ..  获取当前节点的父节点
        @   获取属性
    
            // 位置
            let pathT="/root/books/book/name"
            // 查询所有 符合pathT位置 的节点
            let nameArr=try! doc.nodesForXPath(pathT)
            print(nameArr[0].stringValue())
    
    扩展:
                根名             获取 根名 元素的所有子节点
                /根名            获取 根名 元素的所有子节点
                /根名/元素名      获取 和路径匹配的所有元素节点
                //元素名                获取 元素名相同的所有元素节点
                根名/元素名//元素名      获取 元素名相同的所有元素节点(在根名/元素名 下)
                //@属性名        获取 属性名相同 的所有元素节点
    
    
                /根名/元素名[1]  获取第一个满足path的元素节点
                [last()]         最后一个
                [position()<3]   前2个
                [属性名>3]/元素名
    
                //title[@length]        或取所有 属性名length的元素名title 的元素
                //title[@length='e']    或取所有 属性名length且值为e的元素名title 的元素
    
                *      匹配任何元素节点。
                @*     匹配任何属性节点。
                node()  匹配任何类型的节点。
                |      多个路径
    

    1.1 监测网络状态 (需引入AFN框架)

    1. cocoaPods
        pod 'AFNetworking'
    
    2.AppDelegate+
    #import <AFNetworking/AFNetworking.h>
    
    // 监听网络状态
    -(void)mangeNet{
        // 1.获取网络管理者
        AFNetworkReachabilityManager *netManger=[AFNetworkReachabilityManager sharedManager];
        // 2.网络状态发生变化后调用
        [netManger setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            switch (status) {
                case AFNetworkReachabilityStatusUnknown:{
                    // 检测到网络状态前为此状态
                    NSLog(@"网络未知");
                }
                    break;
                case AFNetworkReachabilityStatusNotReachable:{
                    NSLog(@"连接不到网络");
                    // 提示用户,跳到系统设置页设置网络
                }
                    break;
                case AFNetworkReachabilityStatusReachableViaWWAN:{
                    NSLog(@"流量");
                }
                    break;
                case AFNetworkReachabilityStatusReachableViaWiFi:{
                    NSLog(@"wifi");
                }
                    break;
            }
        }];
        // 3.监测网络变化
        [netManger startMonitoring];
    }
    
        // 获取当前网络状态
        AFNetworkReachabilityStatus status=netManger.networkReachabilityStatus;
    
        // 跳转到设置---蜂窝网络
        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"App-Prefs:root=MOBILE_DATA_SETTINGS_ID"]];
    

    1.2 AFNetworking

    第三方请求网络框架(常用)
    
        // 1.创建网络请求manager
        AFHTTPSessionManager *manger=[AFHTTPSessionManager manager];
        // 1.1 设置request
        // 设置 request类型为二进制类型(默认)
        [manger setRequestSerializer:[AFHTTPRequestSerializer serializer]];
        // 设置 请求超时时间
        [manger.requestSerializer setTimeoutInterval:6.f];
        // 1.2 设置 response
        // 设置 response类型为二进制类型(默认:JSON类型,已经解析)
        [manger setResponseSerializer:[AFHTTPResponseSerializer serializer]];
        // 设置 允许接收的数据类型
        [manger.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html", nil]];
        
        // 2.发送请求
        // url
        NSString *urlStr=@"url";
        // 参数(可以是数组/字典/nil)
        NSDictionary *paraDic=@{@"userId":@""};
        [manger POST:urlStr parameters:paraDic progress:^(NSProgress * _Nonnull uploadProgress) {
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            // 主线程:可以直接更新UI
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@发生错误: \n%@",urlStr,error);
        }];
    
    
        /*
         请求格式
            AFHTTPRequestSerializer            二进制格式        (默认)
            AFJSONRequestSerializer            JSON
            AFPropertyListRequestSerializer    PList(是一种特殊的XML,解析起来相对容易)
         返回格式
            AFHTTPResponseSerializer           二进制格式  (不作任何处理:NSData,当返回的数据不是JSON/XML/plist/image要设置,如:HTML、Text)
            AFJSONResponseSerializer           JSON            (默认)
            AFXMLParserResponseSerializer      XML,只能返回XMLParser,还需要自己通过代理方法解析
            AFXMLDocumentResponseSerializer (Mac OS X)
            AFPropertyListResponseSerializer   PList
            AFImageResponseSerializer          Image
            AFCompoundResponseSerializer       组合
         */
    
    上传
        // url
        NSString *urlStr=@"url";
        // 参数(可以是数组/字典/nil)
        NSDictionary *paraDic=@{@"userId":@""};
        [manger POST:urlStr parameters:paraDic constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            // img->data
            NSData *imgData=UIImagePNGRepresentation([UIImage imageNamed:@""]);
            
            // 设置需要上传的文件(需要上传的文件,后台规定的参数名,文件名,后台规定的文件类型)
            [formData appendPartWithFileData:imgData name:@"headImage" fileName:@"hello.png" mimeType:@"image/png"];
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            //
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            // 上传成功
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@发生错误: \n%@",urlStr,error);
        }];
    

    1.3 NSURLSession

    原生类(目前用)
    
        // 1.创建请求
        NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:@"urlStr"]];
        // 2.创建会话
        NSURLSession *session=[NSURLSession sharedSession];
        // 3.创建任务
        NSURLSessionDataTask *task=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(error==nil){
                NSDictionary *dcit=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
                // 刷新UI在主线程中
            }
        }];
        // 3.1启动任务
        [task resume];
    
    1. 创建NSURLSession(3方式)
    
    方式一    全局Session(有局限)
        NSURLSession *session=[NSURLSession sharedSession];
    
    方式二    自定义Session(常用)
        NSURLSessionConfiguration *connfi=[NSURLSessionConfiguration defaultSessionConfiguration];
        [connfi setTimeoutIntervalForRequest:5];        // 设置请求超时
        NSURLSession *session=[NSURLSession sessionWithConfiguration:connfi];
    
    方式三    后台Session
        NSURLSession *session=[NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    2. 创建NSURLSessionDataTask (4方式)
    
    方式一
        NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
    方式二
        NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(!error){
            }
        }];
    方式三
        NSURLSessionDataTask *dataTask=[session dataTaskWithURL:[NSURL URLWithString:@""]];
    方式四
        NSURLSessionDataTask *dataTask=[session dataTaskWithURL:[NSURL URLWithString:@""] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(!error){
            }
        }];
        [dataTask resume];  // 任务开始
        [dataTask suspend]; // 任务暂停
        [dataTask cancel];  // 任务取消
    
    或
    
    2. 创建NSURLSessionUploadTask(5方式)     上传data
    方式一
        [session uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]] fromData:data];
    方式二
        [session uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]] fromData:data completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(!error){
            }
        }];
    方式三
        [session uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]] fromFile:[[NSURL alloc]initFileURLWithPath:[NSString stringWithFormat:@"%@/Documents/1.txt",NSHomeDirectory()]]];
    方式四
        [session uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]] fromFile:[[NSURL alloc]initFileURLWithPath:[NSString stringWithFormat:@"%@/Documents/1.txt",NSHomeDirectory()]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(!error){
            }
        }];
    方式五
    [session uploadTaskWithStreamedRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
    
    
    或 
    2. 创建NSURLSessionDownloadTask(6方式)下载data
    方式一
        NSURLSessionDownloadTask *dataTask=[session downloadTaskWithURL:[NSURL URLWithString:@""]];
    方式二
        NSURLSessionDownloadTask *dataTask=[session downloadTaskWithURL:[NSURL URLWithString:@""] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(!error){
            }
        }];
    方式三
        NSURLSessionDownloadTask *dataTask=[session downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
    方式四
        NSURLSessionDownloadTask *dataTask=[session downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(!error){
            }
        }];
    方式五
        NSURLSessionDownloadTask *dataTask=[session downloadTaskWithResumeData:data];
    方式六
        NSURLSessionDownloadTask *dataTask=[session downloadTaskWithResumeData:data completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if(!error){
            }
        }];
    
    NSObject
        NSURLSessionTask
            NSURLSessionDataTask         NSURLSessionDownloadTask
              NSURLSessionUploadTask
    
        NSURLSessionUploadTask          上传专用Task(不接收数据)
        NSURLSessionDownloadTask        下载专用Task
        NSURLSessionDataTask            上传数据,并接收返回数据
    
    创建NSURLSessionConfiguration (3方式)
    
      方式一
        // 存储Cache在硬盘(默认模式)(保存用户的证书到钥匙串,使用共享cookie存储)
        NSURLSessionConfiguration *config=[NSURLSessionConfiguration defaultSessionConfiguration];
    
      方式二
        // 存储Cache在内存(会话结束后清空数据,用于无痕浏览)
        NSURLSessionConfiguration *config=[NSURLSessionConfiguration ephemeralSessionConfiguration];
    
      方式三    
        // 将上传下载移到后台
        NSURLSessionConfiguration *config=[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@""];
    
    创建NSURLRequest (3方式)
    方式一
        NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:@""]];
    
    方式二    
        NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:@""] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2];
    
    方式三
        NSMutableURLRequest *muRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@""]];
        // 设置请求超时时间
        [muRequest setTimeoutInterval:10];  
        // 默认GET,设置请求方式
        [muRequest setHTTPMethod:@"POST"]; 
        // 设置请求体
        [muRequest setHTTPBody:[@"key=value&key2=value2" dataUsingEncoding:NSUTF8StringEncoding]];  
        // 设置请求头
        [muRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [muRequest addValue:@"" forHTTPHeaderField:@"Content-Length"];  
    

    1.4 NSURLConnection

    原生类中最早用来请求网络(已过时)
    
        // GET请求
        NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:@"urlStr?key=value&key2=value2"]];
        // POST请求
        NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@""]];
        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:[@"key=value&key2=value2" dataUsingEncoding:NSUTF8StringEncoding]];  
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    
    方式一:使用dele(异步)
    <NSURLConnectionDelegate,NSURLConnectionDataDelegate>
    @property (nonatomic,strong) NSMutableData *contentData;
    
        // 1.创建请求,建立连接
        NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:@"urlStr"]];
        NSURLConnection *conn=[NSURLConnection connectionWithRequest:request delegate:self];
        [conn start];
    
    #pragma mark dele
    // 2.收到响应时调用
    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
        _contentData.length=0;
    }
    // 3.收到数据时调用
    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        [_contentData appendData:data];
    }
    // 4.数据接收完毕后调用
    -(void)connectionDidFinishLoading:(NSURLConnection *)connection{}
    // 4.1连接出错时调用
    -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{}
    
    方式二:sendAsynchronousRequest(异步)
        [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"urlStr"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        }];
    
    方式三:sendSynchronousRequest(同步)
        NSData *contentData=[NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"urlStr"]] returningResponse:&response error:nil];
    
    2. 模型转换

    2.1 JSONModel

    1. cocoaPods引入
    # JSONModel
    pod 'JSONModel'
    
    2. 自定义模型
    #import <JSONModel/JSONModel.h>
    YTPersonModel : JSONModel
    
    // 1.属性是否可选(当有自定义属性不需要转换时+)
    +(BOOL)propertyIsOptional:(NSString *)propertyName{
        return true;
    }
    // 2.当有名字不一样时+ (自定义属性:后台属性)
    +(JSONKeyMapper *)keyMapper{
        return [[JSONKeyMapper alloc]initWithModelToJSONDictionary:@{@"themeId":@"id",@"Description":@"description"}];
    
    /*
            // 去掉_a 改为 A    (将驼峰模式改为下划线模式)
            return JSONKeyMapper.mapperFromUnderscoreCaseToCamelCase()
    */
    }
    
    // 3.有类属性数组   或  作其他处理 +
    -(instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError *__autoreleasing *)err{
    
        self=[super initWithDictionary:dict error:err];
        if(self){
        
            //
            NSArray *dayNumArr=dict[@"tripDayList"];
            _tripDayList=[YTDayModel arrayOfModelsFromDictionaries:dayNumArr error:nil];
            
            // 
            if(dict[@"readyTime"]){  
                _readyTime=[dict[@"readyTime"] intValue];
            }else if(dict[@"redayTime"]){
                _readyTime=[dict[@"redayTime"] intValue];
            }
        }
        
        return self;
    }
    
    3. 使用:
    _guideArr=[YTPublishDZModel arrayOfModelsFromDictionaries:gjArr error:nil];
    

    2.2 MJExtension

    1.cocoaPods导入
    pod 'MJExtension'
    
    2.model
    
    BaseModel.h
    #import <Foundation/Foundation.h>
    @interface BaseModel : NSObject
    // 其他属性(对应)
    @property (nonatomic, copy) NSString *ID;
    @end
    
    
    BaseModel.m
    #import "BaseModel.h"
    @implementation BaseModel
    
    // + description打印所有属性
    MJLogAllIvars
    // 使该model类实现NSCoding协议,用于归档(必须)
    MJCodingImplementation
    
    // 替换不同的字段
    + (NSDictionary *)replacedKeyFromPropertyName{
        
        NSDictionary *dict = @{@"ID": @[@"id",@"houseId"] ,@"descriptions":@"description"};
        return dict;
    }
    // 把null的字段转换为空字符串
    - (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property{
        
        // 把null属性处理成空字符串
        if ([oldValue isKindOfClass:[NSNull class]]){
            
            if (property.type.isNumberType){
                return 0;
            }else if (property.type.isBoolType){
                return 0;
            }else if ([property.type.code isEqualToString:@"NSArray"]){
                return @[];
            }else{
                return @"";
            }
        }
        if (!oldValue){
            if (property.type.isNumberType){
                return 0;
            }else if (property.type.isBoolType){
                return 0;
            }else if ([property.type.code isEqualToString:@"NSArray"]){
                return @[];
            }else if ([property.type.code isEqualToString:@"NSString"]){
                return @"";
            }else{
                return nil;
            }
        }
        
        return oldValue;
    }
    @end
    
    3. 使用
    NSArray *selecteds = [BaseModel mj_objectArrayWithKeyValuesArray:dic[@"response"][@"selected"]
    
    3. 存储
        NSUserDefaults 
        NSCoding归档
        sqlite
        FMDB
        CoreData
        读写文件
    

    3.1 NSUserDefaults

        用于存储基础数据类型,不能存储类类型。
    
        // 设值(必须调用synchronize)
        [[NSUserDefaults standardUserDefaults]setObject:@(10) forKey:@"age"];
        [[NSUserDefaults standardUserDefaults]synchronize];
        // 取值
        [[NSUserDefaults standardUserDefaults]objectForKey:@"age"];
    
    其他设值方式(必须调用synchronize)
        [[NSUserDefaults standardUserDefaults]setBool:true forKey:@"sex"];
        [[NSUserDefaults standardUserDefaults]setInteger:10 forKey:@"age"];
        [[NSUserDefaults standardUserDefaults]setDouble:10.0 forKey:@"weight"];
        [[NSUserDefaults standardUserDefaults]setFloat:10.0f forKey:@"weight"];
    

    3.2 NSCoding

        用于存储类类型。
    
    1. 创建归档类(遵守NSCoding协议实现encodeWithCoder、initWithCoder)
    Student.h
    #import <Foundation/Foundation.h>
    @interface Student : NSObject<NSCoding>
    @property (nonatomic,copy) NSString *name;
    @property (nonatomic,assign) int age;
    @end
    
    Student.m
    #import "Student.h"
    @implementation Student
    // 编码
    -(void)encodeWithCoder:(NSCoder *)aCoder{
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeInteger:self.age forKey:@"age"];
    }
    // 解码
    -(instancetype)initWithCoder:(NSCoder *)aDecoder{
        if(self){
            self.name=[aDecoder decodeObjectForKey:@"name"];
            self.age=(int)[aDecoder decodeIntegerForKey:@"age"];
        }
        return self;
    }
    @end
    
    2.归档、解档
        Student *student=[Student new];
        // 路径
        NSString *path=[NSString stringWithFormat:@"%@/Documents/hello.archive",NSHomeDirectory()];
        // 归档
        [NSKeyedArchiver archiveRootObject:student toFile:path];
        // 解档
        student=[NSKeyedUnarchiver unarchiveObjectWithFile:path];
    

    3.3 sqlite

    SQLite是一个由C编写的SQL嵌入式轻量级关系型数据库(线程不安全)
    
    DBManger.h
    
    #import <Foundation/Foundation.h>
    @interface DBManger : NSObject<NSCopying,NSMutableCopying>
    +(instancetype)sharedSingleton;
    @end
    
    DBManger.m
    
    #import "DBManger.h"
    #import <sqlite3.h>
    
    @interface DBManger()
    @end
    
    @implementation DBManger
    
    
    // ---------- 单例 ---------
    static DBManger *_singleton;
    +(instancetype)sharedSingleton{
        return [self new];
    }
    +(instancetype)allocWithZone:(struct _NSZone *)zone{
        @synchronized (self) {
            if(!_singleton){
                _singleton=[super allocWithZone:zone];
            }
        }
        return _singleton;
    }
    // 避免使用copy mutableCopy方法时再次创建
    -(id)copyWithZone:(NSZone *)zone{
        return _singleton;
    }
    -(id)mutableCopyWithZone:(NSZone *)zone{
        return _singleton;
    }
    
    
    // ------------ 操作数据库 -----------
    static sqlite3 *db = nil;
    
    /*
     打开数据库
     */
    -(void)openDB{
        // 有db则打开,没db则先创建再打开
        NSString *path=[NSString stringWithFormat:@"%@/Documents/test.db",NSHomeDirectory()];
        if(sqlite3_open([path UTF8String], &db)==SQLITE_OK){    // 打开db成功
            NSLog(@"数据库打开成功");
        }
    }
    /*
     关闭数据库
     */
    -(void)closeDB{
        if (sqlite3_close(db) == SQLITE_OK) {
            NSLog(@"数据库关闭成功");
            db = nil;
        } else {
            NSLog(@"数据库关闭失败");
        }
    }
    /*
     创建表
     */
    -(void)createTable{
        //
        [self openDB];
        NSString *sql=@"CREATE TABLE IF NOT EXISTS good(good_id INTEGER PRIMARY KEY AUTOINCREMENT,good_name CHAR(50) NOT NULL DEFAULT 'good',good_content CHAR(200),good_pic CHAR(100));";
        char *error;
        if(sqlite3_exec(db,[sql UTF8String], nil, nil, &error)==SQLITE_OK){
            NSLog(@"创建表成功");
        }else{
            NSLog(@"创建表失败 = %s",error);
        }
        [self closeDB];
    }
    /*
     删除表
     */
    -(void)dropTable{
        //
        [self openDB];
        NSString *sql=@"DROP TABLE good;";
        char *error;
        if(sqlite3_exec(db,[sql UTF8String], nil, nil, &error)==SQLITE_OK){
            NSLog(@"创建表成功");
        }else{
            NSLog(@"创建表失败 = %s",error);
        }
        [self closeDB];
    }
    
    /*
     更新表
     */
    - (void)insertData{
        [self openDB];
        sqlite3_stmt *stmt = nil;
        NSString *sqlStr = @"INSERT good(good_name,good_content) VALUES(?,?);";
        //        sqlStr="UPDATE TABLE good SET good_name=? WHERE good_id=?"
        //        sqlStr="DELETE FROM good WHERE good_name=?"
        if (sqlite3_prepare_v2(db, sqlStr.UTF8String, -1, &stmt, NULL) == SQLITE_OK) {
            // 索引从1开始,代表第几个问号
            sqlite3_bind_int(stmt, 1, 10);
            sqlite3_bind_text(stmt, 2,  sqlStr.UTF8String, -1, SQLITE_TRANSIENT);
            if (sqlite3_step(stmt) == SQLITE_DONE) {
                NSLog(@"新增成功");
            }
        } else {
            NSLog(@"新增数据不合法");
        }
        sqlite3_finalize(stmt);
        [self closeDB];
    }
    
    /*
     查询表
     */
    - (void)queryData{
        [self openDB];
        sqlite3_stmt *stmt = nil;
        NSString *sqlStr = @"SELECT * FROM good";
        if (sqlite3_prepare_v2(db, sqlStr.UTF8String, -1, &stmt, NULL) == SQLITE_OK) {
            if (!(sqlite3_step(stmt) == SQLITE_DONE)) {
                // 单步获取每行(SQLITE_ROW为一行数据)
                while (sqlite3_step(stmt) == SQLITE_ROW) {
                    int ID = sqlite3_column_int(stmt, 0);
                    const unsigned char *name = sqlite3_column_text(stmt, 1);
                    const unsigned char *content = sqlite3_column_text(stmt, 2);
                    const unsigned char *pic = sqlite3_column_text(stmt, 3);
                    NSLog(@"ID = %d , name = %@ , sex = %@, description = %@",ID,[NSString stringWithUTF8String:(const char *)name],[NSString stringWithUTF8String:(const char *)content],[NSString stringWithUTF8String:(const char *)pic]);
                }
            } else {
                NSLog(@"查询语句完成");
            }
        } else {
            NSLog(@"查询语句不合法");
        }
        
        //
        sqlite3_finalize(stmt);
        [self closeDB];
    }
    
    @end
    

    3.4 FMDB

    3.5 CoreData

    3.6 读写文件

    4. 其他相关

    4.1 SDWebImage 第三方加载网络图片

    概念

    SDWebImage
        主线程不会被阻塞(异步下载)
        支持GIF动画
        相同的url不会被下载多次
    
    SDWebImage原理:
        首先从内存中获取数据,如果找的则显示,没找到则从沙盒中查找。沙盒中找到则放入内存中并显示,没找到就从网上下载并放入内存和沙盒中并显示。     
        清理图片缓存:[SDWebImage clear];  
    

    使用

    1. Podfile中+
    
    # SDwebImage
    pod 'SDWebImage'
    
    2.UIImageView
    #import <SDWebImage/SDImageCache.h>
    
        UIImageView *imgV=[UIImageView new];
        [imgV sd_setImageWithURL:[NSURL URLWithString:@""]];
        [imgV sd_setImageWithURL:[NSURL URLWithString:@""] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
        }];
        [imgV sd_setImageWithURL:[NSURL URLWithString:@""] placeholderImage:[UIImage new]];
        [imgV sd_setImageWithURL:[NSURL URLWithString:@""] placeholderImage:[UIImage new] options:SDWebImageRetryFailed];
        [imgV sd_setImageWithURL:[NSURL URLWithString:@""] placeholderImage:[UIImage new] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
        }];
        [imgV sd_setImageWithURL:[NSURL URLWithString:@""] placeholderImage:[UIImage new] options:SDWebImageRetryFailed completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
        }];
        [imgV sd_setImageWithURL:[NSURL URLWithString:@""] placeholderImage:[UIImage new] options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
        } completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
        }];
    
        // 动画
        [imgV sd_setAnimationImagesWithURLs:@[[NSURL URLWithString:@""]]];
        [imgV sd_cancelCurrentAnimationImagesLoad];
    
        /*
         url : 图片地址
         completed : 显示完毕后调用
         placeholderImage : 占位图(图片无法获取时显示)
         options : 下载选项
            SDWebImageRetryFailed(下载失败后重试)
            SDWebImageLowPriority(显示时才下载,默认开始交互时下载不流畅)
            SDWebImageCacheMemoryOnly(只进行内存缓存,不在沙盒中缓存)
            SDWebImageProgressiveDownload(渐进式下载,默认整个图片下载完后才显示)
            SDWebImageRefreshCached(刷新缓存,若地址改变图片不变则使用)
            SDWebImageContinueInBackground(后台下载)
            SDWebImageHandleCookies
            SDWebImageAllowInvalidSSLCertificates(允许使用无效SSL)
            SDWebImageHighPriority(优先下载)
            SDWebImageDelayPlaceholder
            SDWebImageTransformAnimatedImage
         */
    
    SDWebImageManager
        #import <SDWebImage/SDWebImageManager.h>
    
        SDWebImageManager *mangeM=[SDWebImageManager sharedManager];
        // 下载图片
        [mangeM loadImageWithURL:[NSURL URLWithString:@""] options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
        } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
        }];
        // 将图片(对应url)加入到缓存
        [mangeM saveImageToCache:[UIImage new] forURL:[NSURL URLWithString:@""]];
        // 取消所有下载任务
        [mangeM cancelAll];
        // 是否有任务正在下载
        BOOL isRun=[mangeM isRunning];
        
        // 对图片地址url做筛选
        [mangeM setCacheKeyFilter:^(NSURL *url) {
            url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
            return [url absoluteString];
        }];
        // 检测图片是否存在于缓存(异步)
        [mangeM cachedImageExistsForURL:[NSURL URLWithString:@""] completion:^(BOOL isInCache) {
        }];
        // 检测图片是否存在于沙盒(异步)
        [mangeM diskImageExistsForURL:[NSURL URLWithString:@""] completion:^(BOOL isInCache) {
        }];
    
        
        // 缓存key
        NSString *cacheKey=[mangeM cacheKeyForURL:[NSURL URLWithString:@""]];
        // cache(readOnly)
        SDImageCache *imageCache=mangeM.imageCache;
        // (readOnly)
        SDWebImageDownloader *imageDownloader=mangeM.imageDownloader;
    
    dele
        // SDWebImageManagerDelegate
        [mangeM setDelegate:self];
    // 是否下载图片(过滤)
    -(BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL{
        return true;
    }
    // 用image替换url
    -(UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL{
        return nil;
    }
    

    相关文章

      网友评论

        本文标题:网络 模型转换 存储---iOS笔记摘录

        本文链接:https://www.haomeiwen.com/subject/xfnksxtx.html