iOS 学习 - 22 异步解析 JSON,使用 FMDB 存储,TableView 显示
前提是已经知道了有哪些 key 值
Model 类:
.h
@interface ListModel : NSObject @property (nonatomic, copy)NSString *time;
@property (nonatomic, copy)NSString *cname;
@property (nonatomic, copy)NSString *summary;
@property (nonatomic, copy)NSString *title;
@property (nonatomic, copy)NSString *type; - (void)createArray:(NSDictionary *)result
dataSource:(NSMutableArray *)dataSource;
.m
- (void)createArray:(NSDictionary *)result
dataSource:(NSMutableArray *)dataSource
{
UserModel *userModel = [[UserModel alloc]init];
NSArray *array = result[@"news"];
for (NSDictionary *dict in array) {
ListModel *listModel = [[ListModel alloc]init];
listModel.cname = [NSString stringWithFormat:@"%@",dict[@"cname"]];
listModel.summary = [NSString stringWithFormat:@"%@",dict[@"summary"]];
listModel.title = [NSString stringWithFormat:@"%@",dict[@"title"]];
listModel.type = [NSString stringWithFormat:@"%@",dict[@"type"]];
listModel.time = [NSString stringWithFormat:@"%@",dict[@"lastUpdateTime"]];
[dataSource addObject:listModel];
//NSLog(@"cname:%@",listModel.type); //时间戳转换为时间
NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:[listModel.time integerValue]];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yy-MM-dd"];
NSString *beginStr = [formatter stringFromDate:startDate];
listModel.time = beginStr;
if (!([userModel selectTable].count > )) {
[userModel insert:listModel];
}
}
}
FMDB:
- (BOOL)delteSqlite {
if ([self isSqliteExist]) {
NSString *path = [NSTemporaryDirectory()stringByAppendingString:@"user.db"];
NSFileManager *manager = [NSFileManager defaultManager];
NSError *error;
[manager removeItemAtPath:path error:&error];
if (error) {
NSLog(@"delete sqlite failed");
}else{
NSLog(@"delete sqlite success");
}
return YES;
}else{
NSLog(@"sqlite isn't exist");
return NO;
}
return NO;
} #pragma mark - 检测本地文件是否存在
- (BOOL)isSqliteExist {
NSString *path = [NSTemporaryDirectory()stringByAppendingString:@"user.db"];
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:path]) {
NSLog(@"sqlite is exist");
return YES;
}else{
NSLog(@"sqlite isn't exist, prepare to create");
return NO;
}
} #pragma mark -- 建数据库
- (void)openDB {
NSString *path = [NSTemporaryDirectory()stringByAppendingString:@"user.db"];
NSLog(@"path:%@",path);
_db = [FMDatabase databaseWithPath:path];
if ([_db open]) {
//建表
BOOL result = [_db executeUpdate:@"CREATE TABLE IF NOT EXISTS NewsInfo(id integer PRIMARY KEY AUTOINCREMENT,cname text NOT NULL,summary text NOT NULL,title text NOT NULL,type text NOT NULL,time text NOT NULL)"];
if (result) {
NSLog(@"create table success");
}else{
NSLog(@"create tabble success");
[_db close];
}
}else{
[_db close];
NSLog(@"open db failed");
}
} #pragma mark - 查询数据库
- (NSMutableArray *)selectTable
{
if (![_db open]) {
[self openDB];
}
NSMutableArray *tempArray = [NSMutableArray array];
if ([_db open]) {
FMResultSet *resultSet = [_db executeQuery:@"select *from NewsInfo;"];
while ([resultSet next]) {
ListModel *listModel = [[ListModel alloc]init];
listModel.cname = [resultSet objectForColumnName:@"cname"];
listModel.summary = [resultSet objectForColumnName:@"summary"];
listModel.title = [resultSet objectForColumnName:@"title"];
listModel.type = [resultSet objectForColumnName:@"type"];
listModel.time = [resultSet objectForColumnName:@"time"];
[tempArray addObject:listModel];
}
[_db close];
}
return tempArray;
} #pragma mark - 插入进表
- (void)insert:(ListModel *)model
{
if (![_db open]) {
[self openDB];
}
[_db executeUpdate:@"INSERT INTO NewsInfo(cname,summary,title,type,time)VALUES(?,?,?,?,?)",model.cname,model.summary,model.title,model.type,model.time];
} #pragma mark - 修改某个值
- (void)update:(NSString *)value to:(NSString *)key {
if (![_db open]) {
[self openDB];
}
if ([_db open]) {
NSString *updateSql = [NSString stringWithFormat:@"update NewsInfo set %@='%@'",key,value];
BOOL res = [_db executeUpdate:updateSql]; if (!res) {
NSLog(@"error when insert db table");
} else {
NSLog(@"success to insert db table");
}
[_db close];
}
}
VC:
- (void)viewDidLoad {
[super viewDidLoad];
[self addBtn]; self.title = @"新闻";
_userModel = [[UserModel alloc]init];
_dataSource = [[NSMutableArray alloc]initWithCapacity:];
[self.view addSubview:self.tableView]; [self isRequestData];
} #pragma mark - 添加一个删除数据库的按钮
- (void)addBtn {
UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithTitle:@"delete" style:UIBarButtonItemStylePlain target:self action:@selector(deleteSqlite)];
self.navigationItem.rightBarButtonItem = item;
} #pragma mark 删除数据库按钮方法
- (void)deleteSqlite {
[_userModel delteSqlite];
} #pragma mark - 本地数据库有值就不请求数据,取本地数据库值
- (void)isRequestData {
if ([_userModel isSqliteExist]) {
_dataSource = [_userModel selectTable];
dispatch_async(dispatch_get_main_queue(), ^{
[_tableView reloadData];
});
}else{
//创建一个异步队列解析 json,防止阻塞主线程
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, );
dispatch_async(queue, ^{
[self urlStr];
});
}
} #pragma mark -- 解析 JSON
- (void)urlStr
{
NSURL *url = [NSURL URLWithString:URLSTR];
NSURLSession *session = [NSURLSession sharedSession];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSError *error1;
//解析 json,返回字典,这里解析出来是 unicode 编码,不影响正常显示
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error1]; ListModel *listModel = [[ListModel alloc]init];
[listModel createArray:dict dataSource:_dataSource]; //数据源开始是空的,因为网络等原因...等数据源有值了,在主线程刷新 TabelView
dispatch_async(dispatch_get_main_queue(), ^{
[_tableView reloadData];
});
}];
[task resume];
} #pragma mark -- UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _dataSource.count;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cell_id = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
ListModel *listModel = _dataSource[indexPath.row];
cell.textLabel.text = listModel.title;
cell.detailTextLabel.text = listModel.time;
return cell;
} #pragma mark -- UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { ListModel *listModel = _dataSource[indexPath.row];
DetailViewController *detailVC = [[DetailViewController alloc]init];
[self.navigationController pushViewController:detailVC animated:YES];
detailVC.titleStr = listModel.cname;
detailVC.contentStr = listModel.summary;
} #pragma mark -- getter
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc]initWithFrame:self.view.frame];
_tableView.delegate = self;
_tableView.dataSource = self;
}
return _tableView;
}
完整代码,见 github
iOS 学习 - 22 异步解析 JSON,使用 FMDB 存储,TableView 显示的更多相关文章
- 前端学习之——js解析json数组
** 前端学习之——js解析json数组** 解析json数组即对JSONArray的遍历 一.对于标准的json数组如: var result=[{"flag":1," ...
- iOS学习之数据解析
解析:按照约定好的格式提取数据的过程叫做解析; 后台开发人员按照约定好的格式存入数据,前端开发人员按照约定的格式读取数据; 主流的格式: XML / JSON 前端和后台都能识别的格式; XML解析 ...
- 《项目经验》--后台一般处理程序向前台JS文件传递JSON,JS解析JSON,将数据显示在界面--显示在DropDownList 或 显示在动态创建的table中
http://blog.csdn.net/mazhaojuan/article/details/8599167 先看一下我要实现的功能界面: 这篇文章主要介绍:后台一般处理程序把从数据库查找的数据,转 ...
- iOS网络-02-数据解析(JSON与XML)
数据交互格式 服务器返回给用户的数据,通常是以下两种方式: JSON XML JSON 一种轻量级的数据数据格式,体积比XML小,是服务器返回给移动端通常采用的格式 用使用JSON文件中的数据,需要对 ...
- 【原】iOS学习之XML与JSON两种数据结构比较和各自底层实现
1.XML与JSON两种数据结构的优缺点 1> XML 优点: 格式统一, 符合标准 容易与其他系统进行远程交互, 数据共享比较方便 缺点: XML文件格式文件庞大, 格式复杂, 传输占 ...
- ANDROID_MARS学习笔记_S02_013_Gson解析json串
1.MainActivity.java package com.json; import java.io.IOException; import java.io.StringReader; impor ...
- Python学习--22 异步I/O
在同步IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行.而异步IO方式中,线程发送一个IO请求到内核,然后继续处理其他的事情,内核完成IO请求后,将会通知线程IO操 ...
- 【原】iOS学习之UIStoryboardSegue解析
在 Storyboard 的可视化编程中,跳转界面就是按住 Ctrl 使用鼠标头一条连线就可以解决,相当的简单!本篇博客主要就是介绍这条连线,在iOS中,这条连线也是一个对象,也有其自己的初始化方法和 ...
- iOS学习22之视图控制器
1.自定义视图 1> 概述 定义视图:系统标准UI之外,自己组合而出的新的视图. 定义视图的优点: iOS提供了很多UI组件,借助它们我们可以实现不同的功能.尽管如此,实际开发中,我们还需要 ...
随机推荐
- C算法编程题(六)串的处理
前言 上一篇<C算法编程题(五)“E”的变换> 连续写了几篇有关图形输出的编程题,今天说下有关字符串的处理. 程序描述 在实际的开发工作中,对字符串的处理是最常见的编程任务.本题目即是要求 ...
- 基于DDD + SD.Framework实现的统一身份认证系统
项目地址 http://git.oschina.net/lishilei0523/ShSoft.UAC 项目说明 本项目开发的目的有三: 1.作为一个使用SD.Framework框架开发的项目样板 2 ...
- windows配置xhprof,PHP性能分析工具
本来以为配置这么一个工具不会费很大的力气,后面发现完全不是. 一.小插曲 早上显示电脑不能显示虚拟目录下的所有域名,但是能打开localhost,数据库连接也不行了.这个问题纠缠了我一个上午.对了还有 ...
- Stackoverflow/dapper的Dapper-Extensions用法(二)
之前翻译了Dapper-Extensions项目首页的readme.md,大家应该对这个类库的使用有一些了解了吧,接下来是wiki的文档翻译,主要提到了AutoClassMapper.KeyTypes ...
- Oracle管理磁盘空间和资源
1.可恢复的空间分配 2.可移动表空间 3.Oracle段收缩功能 4.Oracle数据库资源管理 Reference 1.可恢复的空间分配 1.1 了解可恢复的空间分配 一般情况,我们发出一个大型数 ...
- 彻底解决低端安卓手机touchend事件不触发(考虑scroll)
本次移动端开发时遇见了安卓4.2系统不能触发touchend的问题,有以下需求. 1. 横滑轮播图 2.下拉刷新页面内容 3.body滚动条不能失效 开始在轮播图touchmove事件中阻止了浏览器默 ...
- 源码阅读系列:EventBus
title: 源码阅读系列:EventBus date: 2016-12-22 16:16:47 tags: 源码阅读 --- EventBus 是人们在日常开发中经常会用到的开源库,即使是不直接用的 ...
- 【PHP面向对象(OOP)编程入门教程】23.自动加载类 __autoload()函数
很多开发者写面向对象的应用程序时,对每个类的定义建立一个 PHP 源文件.一个很大的烦恼是不得不在每个脚本(每个类一个文件)开头写一个长长的包含文件的列表. 在软件开发的系统中,不可能把所有的类都写在 ...
- ThinkPHP中的快捷函数小结
U() 制作url地址的快捷函数 C(名称) 获得配置变量(convertion.php config.php)信息C(名称,值) 设置配置变量信息 L() 获得语言变量信息E() 给页面输出错误信息 ...
- 【处理手记】VS2010SP1安装不上Visual Studio 2010 SP1 SDK的解决办法
想写个VS插件,需要安装VS的SDK,VS2010SP1对应的SDK自然是Visual Studio 2010 SP1 SDK,下载页面: https://www.microsoft.com/en-u ...