美文网首页
XML、沙箱、UserDefaults、归档、sqlite、co

XML、沙箱、UserDefaults、归档、sqlite、co

作者: 我不白先生 | 来源:发表于2020-11-23 10:16 被阅读0次

xml:可扩展标记性语言
应用场景:1.用来封装网路数据(使用的不多 更多的使用json)2.用来做配置文件


image.png

Book.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Book : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *price;
@property(nonatomic,copy)NSString *page;
@property(nonatomic,copy)NSString *author;
@property(nonatomic,copy)NSString *bookID;
@end

BookXMLParser.h

#import <Foundation/Foundation.h>
#import "Book.h"
NS_ASSUME_NONNULL_BEGIN

@interface BookXMLParser : NSObject<NSXMLParserDelegate>
@property(nonatomic,strong)NSMutableArray *books;
@property(nonatomic,copy)NSString *currentString;
-(NSArray *)parseBooksWithXMLFileName:(NSString *)name;
@end

BookXMLParser.m

#import "BookXMLParser.h"
@implementation BookXMLParser
-(NSArray *)parseBooksWithXMLFileName:(NSString *)name{
    self.books = [NSMutableArray array];
    NSString *path = [[NSBundle mainBundle]pathForResource:name ofType:@"xml"];
    //创建系统提供的解析类
    NSXMLParser *parser = [[NSXMLParser alloc]initWithContentsOfURL:[NSURL fileURLWithPath:path]];
    parser.delegate = self;
    //开始解析
    [parser parse];
    return  self.books;
}
//didStartElement已经开始元素
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{
    NSLog(@"开始标签:%@",elementName);
    if([elementName isEqualToString:@"book"]){
        Book *b=[Book new];
        [self.books addObject:b];
        b.bookID = attributeDict[@"bookID"];
    }
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    NSLog(@"发现文本:%@",string);
    self.currentString = string;
}
-(void)parser:(NSXMLParser *)parser didEndElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName{
    NSLog(@"结束标签:%@",elementName);
    Book *b = self.books.lastObject;
    if([elementName isEqualToString:@"name"]){
        b.name = self.currentString;
    }else  if([elementName isEqualToString:@"author"]){
        b.author = self.currentString;
    }else  if([elementName isEqualToString:@"price"]){
        b.price = self.currentString;
    }else  if([elementName isEqualToString:@"page"]){
        b.page = self.currentString;
    }
    
}
@end

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book bookID="1">
        <name>三国演义</name>
        <author>罗贯中</author>
        <price>10</price>
        <page>50</page>
        </book>
    <book bookID="2">
        <name>西游记</name>
        <author>吴承恩</author>
        <price>50</price>
        <page>100</page>
        </book>
    <book bookID="3">
        <name>红楼梦</name>
        <author>曹雪芹</author>
        <price>60</price>
        <page>200</page>
        </book>
    <book bookID="4">
        <name>水浒传</name>
        <author>施耐庵</author>
        <price>30</price>
        <page>150</page>
        </book>
</books>

ViewController.m

#import "ViewController.h"
#import "BookXMLParser.h"
@interface ViewController ()
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    BookXMLParser *parser = [[BookXMLParser alloc]init];
    NSArray *books = [parser parseBooksWithXMLFileName:@"books"];
}

解析方式有两种:
1.SAX解析:逐行解析 节省资源 步骤繁琐
2.Dom解析:把所有数据加载到内存中在内存中构建树桩结构 使用简单

  • 导入三方文件夹TBXML,并且为了顺利导入不报错需要创建PrefixHeader.pch
    写入代码
#import <Foundation/Foundation.h>
#define ARC_ENABLED
#import <UIKit/UIKit.h>

最后一定要创建pch路径


image.png

或者直接拖入pch路径也可
在项目里创建BookXMLParser.m

#import "BookXMLParser.h"
#import "Book.h"
#import "TBXML.h"
@implementation BookXMLParser
+(NSArray *)parserBookWithFileName:(NSString *)name{
    NSMutableArray *books = [NSMutableArray array];
    TBXML *tbXML = [[TBXML alloc]initWithXMLFile:name fileExtension:@"xml" error:nil];
    TBXMLElement *booksEle = tbXML.rootXMLElement;
    TBXMLElement *bookEle = [TBXML childElementNamed:@"book" parentElement:booksEle];
    while (bookEle) {
        Book *book = [Book new];
        book.bookID = [TBXML valueOfAttributeNamed:@"bookID" forElement:bookEle];
        TBXMLElement *nameEle = [TBXML childElementNamed:@"name" parentElement:bookEle];
        TBXMLElement *pageEle = [TBXML childElementNamed:@"page" parentElement:bookEle];
        TBXMLElement *authorEle = [TBXML childElementNamed:@"author" parentElement:bookEle];
        TBXMLElement *priceEle = [TBXML childElementNamed:@"price" parentElement:bookEle];
        book.price = [TBXML textForElement:priceEle];
        book.name = [TBXML textForElement:nameEle];
        book.page = [TBXML textForElement:pageEle];
        book.author = [TBXML textForElement:authorEle];
        [books addObject:book];
        //查找下个兄弟标签
        bookEle = [TBXML nextSiblingNamed:@"book" searchFromElement:bookEle];
    }
    return books;
}
@end

ViewController.m

#import "ViewController.h"
#import "BookXMLParser.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSArray *books = [BookXMLParser parserBookWithFileName:@"books"];
}

沙箱:
Documents:文档 最常打交道 iTunes会备份和恢复此文件的内容
Library/Caches:缓存文件夹 用来保存缓存数据 不会备份和恢复
Library/Preferences:用户偏好设置 iTunes会备份和恢复此文件夹的内容
tmp:临时文件夹 存放临时文件 不会备份和恢复 此文件夹内容会不定时时删除
NSHomeDirectory()获得沙箱根目录的代码
ViewController.m

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //得到沙箱的根目录
    NSString *homePath = NSHomeDirectory();
    //除了通过字符串拼接得到沙箱子文件夹路径之外 还提供了以下几种方式
    NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
    NSString *tmpPath = NSTemporaryDirectory();
    //
    NSLog(@"%@",homePath);
    NSLog(@"%@",documentsPath);
    NSLog(@"%@",cachesPath);
    NSLog(@"%@",tmpPath);
    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"names.plist"];
    NSArray *names = @[@"a",@"b",@"c"];
    [names writeToFile:filePath atomically:YES];
}

数据持久化的四种方式

1.UserDefaults用户偏好设置 用来保存小量数据时使用

image.png

分别拖入这三个控件
分别创建三个控件的属性和事件方法
注意文本控件的事件方法改为Editing change
其他两个空间的时间方法是value change
ViewController.m

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UISlider *mySlider;
@property (weak, nonatomic) IBOutlet UITextField *myTF;
@property (weak, nonatomic) IBOutlet UISegmentedControl *mySC;

@end

@implementation ViewController
- (IBAction)editAction:(UITextField *)sender {
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
     [ud setObject:sender.text forKey:@"text"];
     [ud synchronize];

}
- (IBAction)sliderAction:(UISlider *)sender {
   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    [ud setFloat:sender.value forKey:@"value"];
    [ud synchronize];
}
- (IBAction)scAction:(UISegmentedControl *)sender {
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
     [ud setInteger:sender.selectedSegmentIndex forKey:@"index"];
     [ud synchronize];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    self.myTF.text = [ud objectForKey:@"text"];
    self.mySC.selectedSegmentIndex =[ud integerForKey:@"index"];
    self.mySlider.value = [ud floatForKey:@"value"];   
}

归档 需要把对象保存或者通过网络传输时把对象转成NSData
只有当实现了NSCoding协议的对象才能进行归档
归档1
ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
//    UIView *v =[[UIView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
//    v.backgroundColor = [UIColor purpleColor];
//    [self.view addSubview:v];
    //通过归档把v 转换成NSData第一种方式
//    NSData *viewData = [NSKeyedArchiver archivedDataWithRootObject:v];
//    [viewData writeToFile:@"/Users/zhengyang/Desktop/view.arch" atomically:YES];
    //第二种方式简写
//    [NSKeyedArchiver archiveRootObject:v toFile:@"/Users/zhengyang/Desktop/view2.arch"];
    [NSKeyedArchiver archiveRootObject:self.myView.subviews toFile:@"/Users/zhengyang/Desktop/layout_4_0.arch"];
    
}
//-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//    //把nsdata转回对象(解档)第一种方法
////    NSData *data = [NSData dataWithContentsOfFile:@"/Users/zhengyang/Desktop/view.arch"];
////    UIView *view = [NSKeyedUnarchiver unarchiveObjectWithData:data];
////    [self.view addSubview:view];
//    //第二种方法
//    UIView *view = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/zhengyang/Desktop/view.arch"];
//    [self.view addSubview:view];
}
  • 归档之换版式练习


    image.png

    ViewController.m

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView;
@property(nonatomic)int count;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSString *path = [[NSBundle mainBundle]pathForResource:@"layout_4_0" ofType:@"arch"];
    NSArray *views = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    for(UIView *v in views){
        UIImageView *iv =[[UIImageView alloc]initWithFrame:v.frame];
        iv.image = [UIImage imageNamed:@"timg2"];
        [self.myView addSubview:iv];
    }
    [NSTimer scheduledTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {
        self.count++;
        NSString *path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"layout_4_%d",self.count%4] ofType:@"arch"];
        NSArray *views = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
        NSArray *imageViews = self.myView.subviews;
        for (NSInteger i = 0; i<imageViews.count; i++) {
            UIView *v = views[I];
            UIImageView *iv = imageViews[I];
            [UIView animateWithDuration:1 animations:^{
                iv.frame = v.frame;
            }];
        }
    }];
}

自定义对象的归档

#import "ViewController.h"
#import "Person.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
  
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  //保存用户
//    Person *p = [Person new];
//    p.name = @"xiaoming";
//    p.age = 9;
//    [NSKeyedArchiver archiveRootObject:p toFile:@"/Users/zhengyang/Desktop/person.arch"];
    /************** * 保存多个   *****************************/
    //获取之前保存的person
    NSArray *oldPersons = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/zhengyang/Desktop/persons.arch"];
    //如果有之前的则取出之前的 没有则创建一个空数组
    NSMutableArray *newPersons = [NSMutableArray arrayWithArray:oldPersons];
    Person *p = [Person new];
    p.name = @"xiaoming";
    p.age = 58;
    [newPersons addObject:p];
    [NSKeyedArchiver archiveRootObject:newPersons toFile:@"/Users/zhengyang/Desktop/persons.arch"];
   
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//    Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/zhengyang/Desktop/person.arch"];
//    NSLog(@"%@ %d",p.name,p.age);
    /************** *获取 保存多个person   *****************************/
    NSArray *oldPersons = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/zhengyang/Desktop/persons.arch"];
    for (NSInteger i = 0; i<oldPersons.count; i++) {
        Person *p = oldPersons[I];
        NSLog(@"%@   %d ====%ld",p.name,p.age,i);
    }
}
@end

sqlite(数据库)


image.png
image.png
  • FMDB是对SQLite API轻量级二次封装。所以整体使用思路还是类似SQLite API的思路。由于FMDB是基于SQLite API 的,所以使用FMDB也需要导入SQLite的动态库文件
  • FMDB中除了“查询”以外,任何操作都归属于“更新”行为。
    coreData
    欢迎页面练习
    创建一个UIViewController的类WelcomViewController并带xib,将xib面板背景改为绿色
    AppDelegate.m
#import "AppDelegate.h"
#import "WelcomViewController.h"
@interface AppDelegate ()

@end

@implementation AppDelegate
@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    //得到之前的版本号
    NSString *oldVersion = [ud objectForKey:@"version"];
    NSDictionary *dic = [NSBundle mainBundle].infoDictionary;
    //得到当前版本号
    NSString *currentVersion = dic[@"CFBundleShortVersionString"];
    if (![oldVersion isEqualToString:currentVersion]) {
        //第一次运行
        //把程序的版本号保存到UserDefault里面
        [ud setObject:currentVersion forKey:@"version"];
        [ud synchronize];
        //显示欢迎页面
        self.window.rootViewController = [WelcomViewController new];
    }  
    return YES;
}
image.png
image.png

相关文章

网友评论

      本文标题:XML、沙箱、UserDefaults、归档、sqlite、co

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