云端iclound使用-陈棚
使用NSmetadataQuery查询文档,增加,删除,编辑
界面设计完成后效果如图:

程序清单:FKDiary.h
@interface FKDiary : UIDocument @property (nonatomic,strong) NSData *diaryData;
@property (nonatomic,copy) NSString *fileURL;
@end
程序清单FKDiary.m
#import "FKDiary.h" @implementation FKDiary //保存该对象时自动调用该方法
-(id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
NSLog(@"保存文件到URl %@!",self.fileURL);
if (self.diaryData == nil) {
return [[NSData alloc]init]; }
//将diaryData作为放回值,程序将会把该返回值保存到云端
return [self.diaryData copy];
}
//读取该对象时自动调用该方法
-(BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
NSLog(@"从云端下载的数据为:%@",contents);
//将从云端下载得到的数据赋给diaryData数据
self.diaryData = [contents mutableCopy];
return true;
}
程序清单:FKMasterController.m
#import "FKDiary.h" #import "ViewController.h"
@interface FKMasterController ()<UIAlertViewDelegate>
{
//定义导航栏左边的按钮
UIBarButtonItem *deleteButton;
}
@property (strong,nonatomic)NSMetadataQuery *query;
@property (strong,nonatomic)NSMutableArray *documentFilenames;
@property (strong,nonatomic)NSMutableArray *documentURLs;
@property (strong,nonatomic)FKDiary *chosenDiary; @end @implementation FKMasterController - (void)viewDidLoad {
[super viewDidLoad]; //创建导航栏邮编的按钮
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addDiary)];
//将导航栏按钮设置为导航栏的右边按钮
self.navigationItem.rightBarButtonItem = addButton;
//创建导航栏左边的按钮
deleteButton = [[UIBarButtonItem alloc]initWithTitle:@"删除" style:UIBarButtonItemStylePlain target:self action:@selector(deleteDiary)];
//创建导航栏左边的按niu
self.navigationItem.leftBarButtonItem = deleteButton;
//调用reloadFiles从云端下载文件
[self reloadFiles];
}
-(void)addDiary
{
//使用UIAlertView来获取文件名字
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"输入日记名" message:@"输入日记名称" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"创建", nil];
//设置该UIAlertView的风格为带输入框的UIAlertView
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show]; } -(NSURL *)urlForFilename:(NSString *)filename
{
//获取默认的NSFileManager对象
NSFileManager *fileManager = [NSFileManager defaultManager];
//根据Identifier获取系统的Ubiquity Container
//如果传入nil参数,则默认获取第一个Ubiquity Container
NSURL *baseURL = [fileManager URLForUbiquityContainerIdentifier:nil];
//获取云端Ubiquity Container的Documents子目录
NSURL *pathURL = [baseURL URLByAppendingPathComponent:@"Documents"];
//在Documents子目录下添加文件名,作为保存文件的URL
NSURL *destinationURL = [pathURL URLByAppendingPathComponent:filename];
return destinationURL;
} -(void)reloadFiles
{
//创建一个NSMetataQuery对象
self.query = [[NSMetadataQuery alloc]init];
//设置查询谓词
self.query.predicate = [NSPredicate predicateWithFormat:@"%K like '*.diary'",NSMetadataItemFSNameKey];
//设置查询范围,此处指定查询范围为NSMetadataQueryUbiquitousDocumentsScope
// 即在云端的Documents目录下查询
self.query.searchScopes = [NSArray arrayWithObject:NSMetadataQueryUbiquitousDataScope];
//获取数据结束时激发updateUbiquitousDocuments方法
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(updateUbiquitousDocuments:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];
//查询更新完成时激发updateUbiquitousDocuments方法
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(updateUbiquitousDocuments:) name:NSMetadataQueryDidUpdateNotification object:nil]; //开始查询
[self.query startQuery];
} -(void)updateUbiquitousDocuments:(NSNotification *)notification
{
self.documentURLs = [NSMutableArray array];
self.documentFilenames = [NSMutableArray array];
//对查询结果进行排序,排序所使用的比较标准是创建时间
NSArray *results = [self.query.results sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSMetadataItem *item1 = obj1;
NSMetadataItem *item2 = obj2;
//比较两个NSMetadataItem的时间
return [[item2 valueForAttribute:NSMetadataItemFSCreationDateKey] compare:[item1 valueForAttribute:NSMetadataItemFSCreationDateKey]];
}];
//遍历查询结果
for (NSMetadataItem *item in results) {
//查询结果中包含的NSURL属性
NSURL *url = [item valueForAttribute: NSMetadataItemURLKey];
//将NSURL添加到documentURLs集合中
[self.documentURLs addObject:url];
//将NSURL的最后一个路径(文件名)添加到documentfilenames集合中
[self.documentFilenames addObject:url]; }
//控制界面上表哥重新加载数据
[self.tableView reloadData]; }
-(void)perpareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//如果sender等于self,则表明是新建FKDiary后导航到查看,编辑日记的视图空孩子气
if (sender == self) {
UIViewController *destination = segue.destinationViewController;
//将用户新建的FKDiary对象传给目标视图控制器
if ([destination respondsToSelector:@selector(setDetailItem:)])
{
[destination setValue:self.chosenDiary forKey:@"detailItem"];
}
}else
{
//获取激发视图切换的单元格所在的NSIndexPath
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
//获取激发视图切换的单元格中显示的文件名
NSString *filename = [self.documentFilenames objectAtIndex:indexPath.row];
//获取该文件名对应的FKDiary的存储URL
NSURL *docURl = [self urlForFilename:filename];
//以指定的docUrl创建FKDiary对象
self.chosenDiary = [[FKDiary alloc]initWithFileURL:docURl];
//读取chosenDiary文档
[self.chosenDiary openWithCompletionHandler:^(BOOL success) {
//如果读取成功
if (success) {
ViewController *destination = (ViewController *)segue.destinationViewController;
//将读取成功的chosenDiary传给destination
destination.detailItem = self.chosenDiary;
//调用destination的changeDisplay更新显示
[destination changeDisplay];
}
else
{
NSLog(@"failed to load!");
}
}];
}
}
-(void)deleteDiary
{
//使用动画切换表格的编辑状态
[self.tableView setEditing: !self.tableView.editing animated:YES];
//修改deleteButton按钮的文本
deleteButton.title = [deleteButton.title isEqualToString:@"删除"]?@"完成":@"删除"; } - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.documentFilenames count];
} #pragma mark - UIAlertViewDelegate
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1) {
//获取用户zaiUIAlerView中输入的文件名,并添加.diary扩展名
NSString *filename = [NSString stringWithFormat:@"%@.diary",[alertView textFieldAtIndex:0].text];
//获取云端文档存储的url
NSURL *saveURL = [self urlForFilename:filename];
//创建一个fKDiary (UIDocument的子类)对象
self.chosenDiary = [[FKDiary alloc]initWithFileURL:saveURL];
//保存chosenDiary文档
[self.chosenDiary saveToURL:saveURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if(success)
{
NSLog(@"保存成功");
[self reloadFiles];
//执行masterTodetail segue,导航到查看,编辑日记的视图控制器
[self performSegueWithIdentifier:@"masterToDetail" sender:self]; }else
{
NSLog(@"保存失败");
}
}];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
//根据单元格所在的行号获取对应的文档名
NSString *path = [self.documentFilenames objectAtIndex:indexPath.row];
//设置该单元格的文本为文档名取消后缀
cell.textLabel.text = path.lastPathComponent.stringByDeletingPathExtension;
// Configure the cell... return cell;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
//返回UITableViewCellEditingStyleDeleter代表删除
return UITableViewCellEditingStyleDelete;
} /*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/ // Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
//获取用户视图删除的行号
NSInteger rowNo = [indexPath row];
//调用NSfileMangaer的removeItemAtURL:error:方法即可删除云端文档
[[NSFileManager defaultManager]removeItemAtURL:[self.documentURLs objectAtIndex:rowNo] error:nil];
//从底层NSArray集合中删除指定数据项
[self.documentFilenames removeObjectAtIndex:rowNo];
//从UITableView程序界面删删除指定表格行
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
云端iclound使用-陈棚的更多相关文章
- 使用MediaPlayer框架实现简单音乐播放器-陈棚
该项目需要使用MediaPlayer框架,因此程序需要先为该项目添加MediaPalyer框架,并在上面控制器类的实现部分使用#import<MediaPlayer/MediaPlayer.h& ...
- 使用GDataXML生成、修改XML文档-陈棚
使用GDXML生成XML文档的步骤如下. 1.调用GDataXMLNode的elementWithName:方法创建GDataXMLElement对象,对象作为XML文档的根元素. 2.调用GData ...
- 自定义带图片和文字的Button的排版--陈棚
自定义button,动态加载图片与文字 [footView addSubview:btnAllChoose]; [btnAllChoose setTitle:str forState:UIContro ...
- CTO对话:云端融合下的移动技术创新
云端融合真的来了?快听CTO们怎么讲云端融合下,技术创新怎么破? 快听CTO箴言 云喊了很多年,对于很多普通的技术人,心中有很多疑问:云端融合到底意味着什么,对公司的技术体系有什么影响,未来又会走向 ...
- 从云端到边缘 AI推动FPGA应用拓展
近日,全球最大的FPGA厂商赛灵思宣布收购深鉴科技的消息,引发人工智能芯片行业热议,这也是首起中国AI芯片公司被收购的案例.值得注意的是,收购深鉴科技的赛灵思在2018年下半年重点发展方面是汽车自动驾 ...
- (转)利用libcurl和国内著名的两个物联网云端通讯的例程, ubuntu和openwrt下调试成功(四)
1. libcurl 的参考文档如下 CURLOPT_HEADERFUNCTION Pass a pointer to a function that matches the following pr ...
- (转)linux下和云端通讯的例程, ubuntu和openwrt下实验成功(二)
前言: 上节用纯linux的函数实现了和云端通讯, 本节开始利用传说中的神器libcurl 话说一个网络程序员对书法十分感兴趣,退休后决定在这方面有所建树. 于是花重金购买了上等的文房四宝. 一 ...
- (转)linux下和云端通讯的例程, ubuntu和openwrt实验成功(一)
一. HTTP请求的数据流总结#上传数据, yeelink的数据流如下POST /v1.0/device/4420/sensor/9089/datapoints HTTP/1.1Host: api. ...
- MVP社区巡讲-云端基础架构:12月5日北京站 12月12日上海站
紧跟当今的技术发展趋势还远远不够,我们要引领变革!加入本地技术专家社区,获取真实案例.实况培训演示以及探讨新一代解决方案.在此活动中,您将: 了解如何运用开源(OSS)技术.Microsoft 技术及 ...
随机推荐
- 使用 JavaScript 的 HTML 页面混合、JavaScript 文件引用和 HTML 代码嵌入 3 种方式在 HTML 页面上打印出“点击我进入到百度首页”的超链接
查看本章节 查看作业目录 需求说明: 使用 JavaScript 的 HTML 页面混合.JavaScript 文件引用和 HTML 代码嵌入 3 种方式在 HTML 页面上打印出"点击我进 ...
- 【MySQL作业】多字段分组和 having 子句——美和易思分组查询应用习题
点击打开所使用到的数据库>>> 1.按照商品类型和销售地区分组统计商品数量和平均单价,并按平均单价升序显示. -- 按照商品类型和销售地区分组统计商品数量和平均单价,并按平均单价升序 ...
- 【MySQL作业】分组查询 group by 子句——美和易思分组查询应用习题
点击打开所使用到的数据库>>> 1.按照商品类型分组统计商品数量和平均单价,并按平均单价升序显示. -- 按照商品类型分组统计商品数量和平均单价,并按平均单价升序显示: select ...
- 编写Java程序,演练静态内部类应用
返回本章节 返回作业目录 需求说明: 创建一个Person类,在该类中定义一个Home静态内部类,并在这个Home类中定义一个显示Home相关信息的方法. 在Person类中设置一个Home类型属性对 ...
- 深入 Laravel 内核之观察者模式
装饰模式核心内容: 观察者模式又称为发布订阅模式,定义了对象间的一对多依赖关系,当一个对象状态发生改变时,其相关依赖的其他对象都能接收到通知: 观察者模式的核心在于目标(Subject)和观察者(Ob ...
- Ubuntu18.04编译Fuchsia
编译环境 系统:Ubuntu 18.04.1 LTS 64-bit 内存:8 GiB CPU:Intel Core i5-4200M CPU @ 2.50GHz × 4 1.安装编译环境 sudo a ...
- python selenium + web自动化,切换到新的窗口,元素定位不到?
问题描述: 自动化由首页切换到分页面,打开了一个新的窗口,不过,定位不到这个窗口的元素,通过开发者工具是可以查到这个元素的 原因是: 因为窗口句柄还停留在上一个页面,所以导致无法定位元素.报错 &qu ...
- Echart可视化学习(十一)
文档的源代码地址,需要的下载就可以了(访问密码:7567) https://url56.ctfile.com/f/34653256-527823386-04154f 官网找到类似实例, 适当分析,并且 ...
- LINUX学习-Mysql集群-一主多从
新建一台服务器 192.168.88.40 yum -y install mysql mysql-server 编辑etc下的配置文件 vim /etc/my.cnf 输入 bin-log=mysql ...
- C#服务器端使用office组件
http://www.myexception.cn/asp-dotnet/386522.html 不装office那就把Interop.Excel.dll Interop.Office.dll Int ...