十大免费移动应用框架测试框架哪个好

移动应用的类别移动应用按架构可分成三大类。要做好性能测试的, 有必要了解各种应用的种类和内部架构。我们来分别介绍一下各类app的基本情况。本地应用需要从网上商店下载并安装在特定移动设备上的可划分到这一类。这类应用由特定编程语言(例如安卓系统上用的Java和iOS系统上用的Object-C)编写,结合特定移动设备的开放API。用户将这种应用安装到移动设备上之后,无需连接到互联网就能使用。游戏应用程序和从网上商店下载的app就是很好的例子。联网应用通过移动设备上的浏览器访问的应用叫做联网应用。这类应用是通过网络技术如HTML,JQuery和JavaScript开发的。热门社交网站,如Facebook()和Gmail()等都专门开发了基于移动设备的联网应用,倍受移动用户亲睐。混合应用联网应用和本地应用的结合被称作混合型应用。在这类应用里,联网应用被内嵌到本地移动应用中。用户界面像本地应用,内容却需要联网加载。安装在移动设备上的Facebook,Linkedin和Twitter应用是这类“本地界面,联网内容”的最佳典范。提高移动应用性能的重要性随着手机使用量的增加,手机性能的重要性也日益显著。手机用户对性能期望非常高,希望手机应用能像在电脑上运行那么快。据统计:71%用户希望在手机上打开网页能同电脑上一样快5秒钟被认为是用户能忍受的最长响应时间 如果响应时间超过5秒,74%上网用户和50%移动应用用户会放弃三分之一失望的用户会转向竞争对手的应用通常,手机用户会尝试两次,如果第三次依然出现同样问题,半数人再也不会使用该应用。比起桌面程序,手机应用的架构更加复杂,可用资源相对更少,提高和维持快速的响应时间比桌面程序更困难。测试移动应用的挑战做好性能测试,从来就不是一件简单容易的事。搭建与生产环境相同的性能测试环境一直是做性能测试的第一步,也是很重要的一步。然而,由于其复杂的架构,测试手机程序和网站显得更加困难。要覆盖到不同种类(联网,本地和混合应用)、不同平台(iOS,安卓等等)和不同网络环境(Wifi,2G,3G,3G+,4G LTE)也是手机测试面临的一大难题。下面介绍一下几个手机性能测试相关的主要难题。模拟移动网络的互联网连接 与桌面程序的高带宽相比,大多数手机用户使用的3G,3G+和4G LTE网络更慢,无线连接更差。性能测试要模拟不同手机网络的接入情况,这对性能测试人员来说并非易事。移动设备种类繁多市面上有成千上万手机厂商,每个手机厂商倾向于使用不同的操作系统和手机配置。而且,即便是同一个品牌的手机,也有无数的影响因素,每个手机模型都有特定的配置,比如操作系统,处理器,内存和屏幕尺寸等等。测试手机应用时,这些因素或多或少都应该被考虑到,绝对不是件轻松的事。面对这种情况,选择一中功能够用的性能测试工具变得越来越重要。用户数量巨大随着时间的推移,使用智能手机商务应用的用户会急剧增加,越来越多的用户会通过手机处理重要业务。用户数量增加,相应的网络应用也需要增加。你不仅仅要满足现有用户需要,还要适时地增加新功能,这对任何手机应用都是极其重要的。桌面端网络应用和手机应用的差别不管是桌面端网络应用还是手机应该,性能测试的基本原理是相似的,尤其是对于手机网络应用的测试。两者使用相同的技术,你也不用为手机应用选择特别的性能测试工具。测试工具只需要具备基本的性能测试能力,测试人员基本上会用就行了。尽管如此,手机应用和桌面应用还是有如下几个本质上的区别:客户端模式传统网络应用运行在胖客户端上,而手机应用使用的是瘦客户端。胖客户端直接从服务器端访问应用,而不像瘦客户端那样需要将数据通过信号塔中转,因而它比瘦客户端吞吐量更大,速度更快。网络带宽网络带宽在性能中担当重要角色,现今的桌面端应用极大地得益于高速网络。移动网路也在带宽方面不断进步,不过任然无法与前者相提并论。大多数用户在低于3G或4G的网络下使用手机,应用的会话时间延长,用户的响应时间也响应增加,同时也消耗了更多电量。相比桌面应用,带宽是导致手机应用性能差的最大原因。数据传送与桌面端应用强大的CS架构不同,手机数据得依靠信号塔传送到用户设备上。信号塔之间的数据传送一直以来都很慢,也使得手机应用性能变差。设备电量网络应用可以借助桌面电脑的高速处理器和内存最大化地提高性能,然而移动设备的资源却非常有限。移动设备只能依靠有限的电池和内存资源。操作方式不像桌面应用那样通过点击鼠标来操作,移动设备使用手指操作从而获得更好的用户体验。手指操作不如鼠标来得快。何况,设备其实需要将触摸动作翻译成点击。数据使用在移动网路中,流量是收费的。数据缓存技术是桌面应用中提高用户体验的常用手段,但由于流量限制,此项技术在移动应用中无法实现。性能指标由于架构不同,网络和移动应用的性能指标也有些许差别。除了常规指标如响应时间和资源利用量之外,还需要监控电池消耗、二进制大小等等。手机性能测试基础和最佳实践本地手机应用脚本的录制你需要一个移动设备或模拟器来录制用户在本机移动应用上的操作。为了测试应用的性能而录制用户操作,需要暂时关闭移动设备或模拟器上的其他网络流量。你需要一个额外的设备来记录手机或模拟器上的流量,而这个设备可以代替移动设备或模拟器接入互联网。如果用来录制的设备是运行在防火墙之后的,那就不可能获得从3G或4G网络里的流量记录。解决这个问题的方法是将移动设备设置为代理录制器。强制让数据从录制代理里通过,就可以直接用移动设备来录制用户操作。网络手机应用脚本的录制从手机网络应用抓取用户操作与桌面网络应用相似,因为两者沿用了类似的架构。为简单起见,可以用桌面网页浏览器来录制移动网络应用的用户操作。不过,你需要修改用户请求,伪装成是来自移动设备而不是桌面电脑。浏览器插件可以修改用户代理,让请求看起来像是通过移动设备发出的。除此之外,最新的桌面网页浏览器需要支持最新的移动应用技术如HTML5等等。混合移动应用脚本的录制就像手机网络应用一样,桌面网页浏览器也可以用来录制各种各样的混合移动应用。你可以直接浏览到该手机应用的URL地址,然后做性能测试,就像测试单纯的网络应用一样。准确评估应用程序的性能,必须识别并模拟最类似现实情况的设置。合理的负载模型是实现预期效果的关键。不同用户的互联网接入情况不尽相同(例如,Wifi,3G和4G),成功的性能测试必须覆盖所有的情况。所有流行的手机应用性能测试工具都可以模拟真实世界的各种网络连接。另外,根据具体的功能,模拟不同地理区域的大用户负责也很重要。好的性能测试工具像AgileLoad可以借助基于云的性能测试模拟不同地理位置的大用户负载。测试的执行过程是被监控的,在所有针对不同用户负载的应用程序响应被测试完之后,其结果也会对比事先定义好的服务水平协议得到全面的分析。好的性能测试工具如AgileLoad,也提供问题诊断功能,帮你找出根本原因从而快速解决。移动应用性能优化技术移动应用的性能优化技术取决于特定的应用极其瓶颈特性。我们在这里分享几个通用的优化移动应用性能的技巧:减少客户端到服务器的HTTP请求数量,可以缩短页面加载时间将JavaScript和CSS打包成文件并在多个页面之间共享,也是优化性能的好办法尽管浏览器缓存在移动应用上不那么凑效,但可以用HTML5的网页存储技术替代使用内嵌脚本资源,链接引用会极大地延长加载时间压缩或尽量减少界面资源,少占带宽,也能提高速度根据屏幕尺寸裁剪图像, 不仅能减小图片大小,还能提高处理速度总结移动应用日益普及,其重要性也日益增加,这已是不争的事实。优秀的用户体验将成为让用户驻足的原因之一。移动应用的性能测试原理与传统桌面应用并无二致。但是,要全面测试移动应用的性能参数,测试人员需要理解各种移动应用的架构和它们与桌面应用的根本区别,例如带宽,处理器,屏幕尺寸等等。欢迎关注我们的公众号testtao,每日发布最新招聘信息,测试资讯。测试之道网招募公益讲师,欢迎乐于分享的资深测试工程师联系进行自荐和推荐。测试之道新微信公众号testtao,大家快快关注起来!长按下面的二维码,选择“识别图中的二维码”可以快速关注!测试之道(testtao) 
 文章为作者独立观点,不代表微头条立场
的最新文章
TermsVSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)RSS- ResiHDFS(Hadoop Distributed File System )Hadoop分布式文件系统。是根据如何来建立一个高效的测试团队呢?这个问题,一定是“仁者见仁,智者见智”的问题。 1 测试团队中的“人”首先,本文节选自网易高级测试经理宾峥个人分享
适看人群:测试工程师/项目经理/计算机专业学生数据库测试包括测试实际数据(内容)以及数据完整性,已经确保数据没有被误用以及规划的正确性,同时也对数据库应用本周,英特尔宣布,公司计划在全球削减12000名员工。裁员是公司重组的一部分,英特尔寻求转型,将从个人计算机薪资福利是候选人最为关注的问题,但是在日常沟通中,100offer的招聘体验师发现很多候选人并没有恰当的薪资1. 工具无法取代思考在我多年的咨询生涯中,每当坐下来与管理者合作解决问题时,经常会遇到这样的情况:管理者认前言:  本文主要针对http接口进行测试,使用Jmeter工具实现。  Jmter工具设计之初是用于做性能Cross Platform GUI Test Automation tool Linux version (点击上方公众号,可快速关注)英文:Tristan de Montebello译文:Jodoo 链接:httRick Webb 写了一篇关于阅读的好文,提到了他一年要读 60 本书,而他却是一个手头事情很多、忙忙碌碌的专业人士,那么他的阅读习惯是什么呢?我这里借鉴了他的观点,也加入了一些我自己的想法。包括测试实际数据(内容)以及数据完整性,已经确保数据没有被误用以及规划的正确性,同时也对数据库应用(例如,S前言  iOS 开发从 2010 年开始在国内不断地升温,开发和测试相关的问题不绝于耳。iOS 测试主要涉及二.性能测试脚本自动建立测试datapool在robot中tools->session record opt 目的是验证软件系统是否能够达到用户提出的性能指标,同时发现软件系统中存在的性能瓶颈,优化软件,最后起到优化性能测试的工作千头万绪,最怕的就是像无头苍蝇般盲目地测试,不但旷日费时,还累积不到经验,团队与个人都难以成长不知不觉已经从事软件测试六年了,2006毕业到进入外包公司外包给微软做软件测试, 到现在加入著名的外企。六年一、抓包工具各自的特点:  1、httpwatch  特点:嵌入浏览器的抓包工具,结合浏览器使用界面清晰,在软件性能测试过程中,测试数据的准备是一个非常系统化、工作量非常庞大一项工作。如何准备支持不同业务操作、不同Mysql清空表是很重要的操作,也是最常见的操作之一,下面就为您详细介绍Mysql清空表的实现方法,希望能够性能测试的接口测试方式:1.
Web Service协议启动LR选择 Web Service1.无参数testcase设计场景
(1) 接口返回数据为空
(2) 接口返回数据量大 2.单1、背景  1.1 Web程序中的接口  1.1.1 典型的Web设计架构  web是实现了基于网络通信的浏提问:游戏测试面试时,面试官问还有什么问题?   会员蔡亮回答:  面试最后环节,面试官往往会问你还有什么问一、抓包工具各自的特点:  1、httpwatch  特点:嵌入浏览器的抓包工具,结合浏览器使用界面清晰,方一:邮箱输入框  1:不输入任何字符  2:输入中文空格  3:输入英文空格  4:字符串中没有@和点
例最近部门整理了今年所有项目测试团队提出的BUG,筛选了几十个作为常规通用的缺陷,我根据这些缺陷内容,去掉和业在移动互联时代,每个人的智能手机上都安装了各种各样的APP,那我们在使用这些APP的时候都会用到找回密码软件测试上线的标准是什么?既定周期(几轮测试用例跑完)完成就结束?搞定所有bug?领导说了算?集体讨论决定今天测试软件时,遇到一个bug,因为开发说那边不复现,所以为了更好追踪这个问题,需要抓取复现步骤的log. 假如我们需要开发一个程序来展示一个人穿衣服的过程。#encoding=utf-8__author__ = 安装安装手册是否规范,是否简洁,是否通俗易懂。安装手册是否齐全,正确,有改动时,文档是否同步更新直接复制安测试需求:用户从客户端登录到服务器(服务器有多个,根据规则分配),在客户端上传一个文件,文件先上传到服务器在跟使用Loadrunner工具使用者交流的过程中,经常有人提到这个问题,基于HTML(HyperText二、常见报错codec can't encode characters的原因python的程序经常会报错co移动应用的类别移动应用按架构可分成三大类。要做好性能测试的, 有必要了解各种应用的种类和内部架构。我们来分别testtao软件测试公益社区,定期分享最新业界资讯,优质招聘信息。热门文章最新文章testtao软件测试公益社区,定期分享最新业界资讯,优质招聘信息。10689人阅读
移动(33)
在本文中,我们盘点了过去的一年里,最受开发者喜爱的跨平台应用及游戏开发工具,尤以HTML/JS/CSS为众,却也包含使用其他语言进行开发的工具,比如Xamarin,使用C#,就能开发出运行于各大主流移动平台上的原生App。
成本低、周期短,易于上手,不用重新设计,种种好处让跨平台开发风头无量,也让诸多跨平台开发工具趁势崛起。在本文中,我们盘点了过去的一年里,最受开发者喜爱的跨平台移动应用开发工具,尤以HTML/JS/CSS开发为众,比如PhoneGap、Sencha Touch等,却也包含使用其他语言进行开发的工具,比如Xamarin,使用C#,就可以开发出能运行于各大主流移动平台之上的原生App。
HTML/JavaScript/CSS篇
说到跨平台开发工具,很多人首先会想到PhoneGap。这样一款能够让开发者使用HTML、JS、CSS来开发跨平台移动App的开源免费框架,一直以来都深受开发者喜爱,从iOS、Android、BB10、Windows Phone到Amazon Fire OS、Tizen等,各大主流移动平台一应俱全,还能让开发者充分利用地理位置、加速器、联系人、声音等手机核心功能。
此前,在Native与Web谁主未来的大论毫无消停之时,许多人认为,类PhoneGap的应用开发框架天然优势在于支持跨平台,后期可扩展性较强,开发周期很短,熟悉Web技术的开发者可轻松上手,缺点在于性能上的确不如Native,后期还需针对各个版本分别优化开发等。如今,Hybrid App已然当家做主,PhoneGap在性能与平台特性支持上也有着极大的提高和改善,大有赶超Native之势。
相关链接:
Sencha Touch是一款基于HTML5、CSS3和JavaScript的移动Web应用开发框架,内置MVC系统,能够让开发者的HTML5应用看起来就像原生应用一样,全面兼容iOS、Android、BlackBerry、Windows Phone、Tizen等主流移动平台。除了常见的触摸手势之外,Sencha Touch还专为iOS、Android设备提供了单击、双击、滑动、滚动和双指缩放手势。&
HTML5应用开发的大热让众多跨平台开发框架逐渐风行,而Sencha Touch就是其中之一。能够让开发者以非常友好的方式从HTML5/CSS3/JS提取最多内容,并为其提供丰富而又易于使用的特性。Sencha Touch对于iOS平台的兼容性非常好,画面切换效果亦是相当流畅。
相关链接:
Titanium是Appcelerator公司旗下的一款开源的跨平台开发框架,和PhoneGap及Sencha Touch一样,都是让开发者使用HTML/CSS/JS来开发出原生的桌面及移动应用,还支持Python、Ruby和PHP。Titanium最大的特点就是,由于是基于硬件的开发,开发过程中所创建的应用可选择存储在设备或云端之上。
Titanium主要特性:
通过其单一的JavaScript SDK开发原生iOS、Android、Hybrid及移动Web应用。通过其基于Eclipse的Titanium Studio,可以极大地简化开发流程。拥有高效代码块,让开发者编写更少的代码,创建出可扩展的应用程序。集成了MBaaS和Appcelerator Open Mobile Marketplace。
相关链接:
Intel XDK的前身是AppMobi XDK,是一款帮助开发者使用HTML5开发移动及Web应用的跨平台开发工具。XDK包括了一个HTML5开发环境和一组支持创建混合iOS及Android应用的云服务,这些应用能够直接提交到不同的应用商店之中。除此之外,XDK还提供了调试工具,可以进行屏幕仿真调试、设备实际调试和遥控调试,不包括Ad-Hoc模式和安全特性。&
和其他工具相比,XDK兼容PhoneGap的HTML5多平台开发项目,能够极大地减少开发时间,不依赖于Java或任何特定的浏览器特性,还能访问设备自带功能,例如GPS、加速计、摄像头、触摸屏交互、触摸手势、振动等。&
相关链接:
摩托罗拉旗下的HTML5应用开发平台RhoMobile Suite也是相当受开发者欢迎。通过RhoMobile,开发者无需考虑设备类型、操作系统、屏幕尺寸等诸多问题,只需掌握HTML和Ruby就可开发出运行在iOS、Android、Windows Mobile、BlackBerry、Windows Phone等平台上的App。
RhoMobile主要由三部分组成,分别为:
RhoConnect:通过它,应用与数据之间可快速建立连接,并确保用户可以访问这些数据。RhoElements:开发者可以开发出在每台支持设备上都具有相同的外观、感觉和操作灵活的应用。RhoStudio:通过RhoStudio全功能模拟器,开发者可以在PC上快速测试和调试跨平台应用程序。
在过去的一年里,Xamarin的势头可以说是颇为强劲,而其跨平台应用开发工具使用份额比也有着显著增加。通过Xamarin,开发者只需使用C#语言即可开发出iOS、Android、Mac及Windows原生App,不仅可以实现“一次编写,随处运行”,更可达到原生UI的跨平台效果。与基于HTML/JS/CSS的PhoneGap相比,Xamarin最大的优势是通过与系统的底层API通信并与系统原生UI直接交互,可以保证应用的高性能和UI流畅性。
Xamarin主要特性:
快速开发移动原生应用程序代码共享与Visual Studio整合确保第一时间更新原生的用户接口及效能
相关链接:
Corona SDK是Corona Labs旗下的一款专门用于跨平台移动应用开发的Lua语言SDK库,不仅容易入手,无门槛,而且效率也相当高。Corona SDK提供了跨平台能力,所以开发者的应用或游戏可兼容iOS、Android、Kindle Fire和Nook平台。Corona支持硬件加速、GPS、照相机等,并集成了Box2D物理引擎。
Corona SDK服务分为三种:
基础版:能够在极短的时间内完成应用或游戏开发,通过内付费或广告盈利。专业版:增加了先进的图形技术及所有Corona插件等。企业版:开发者可以在线开发,并从Corona应用中调用任何原生库。
相关链接:
其他语言篇
LiveCode是由RunRev公司推出的一款强大的图形化开发环境,不仅免费,还可以提供10倍的效率提升并减少90%的代码。其强大之处在于非常容易学习和使用,可以让一个不会编程的人在很短的时间内就能开发出原生的,能够运行于PC、服务器、移动设备上的应用程序。
LiveCode拥有一个类似于VB的所见即所得的界面设计工具,用户可以使用拖拽的方式来实现应用界面的设计和布局,并通过一种类似于英语的自然脚本语言来编写应用功能,最后,通过LiveCode强大的部署工具来生成可运行于Mac、Windows、Linux、iOS、Android等各种平台上的应用程序。
相关链接:
游戏开发篇
最后,我们再来介绍两款跨平台游戏引擎,分别为Unity、MoSync。
Unity在全球开发者圈子里的受欢迎程度自不必多言,这样一款功能强大的跨平台游戏引擎,全面覆盖了Windows、Mac、iOS、Android、Windows Phone、BlackBerry、Xbox360、Wii等桌面、移动及掌机平台,支持JavaScript、C#、Boo三种脚本语言,拥有着大量的第三方插件和工具,可以帮助开发者极大地提升工作效率。
容易上手、多语言编程、专业级的效果、傻瓜式的调试和编译、强大的扩展性,在跨平台、光影特效及模型渲染等各方面都有着非常不错的表现,让Unity无论在3D还是2D游戏开发中都是当之无愧的“最好用的游戏引擎之一”。
相关链接:
MoSync是一款开源的免费移动游戏开发引擎,易于移植,允许开发者使用C/C++、HTML5或JavaScript来为iOS、Android、Windows Phone、Java Mobile、Windows Mobile等平台进行游戏应用开发。开发者可通过MoSync精简库调用本地设备API,并且,所开发的App还能使用本地的UI控件。
通过MoSync精简库,开发者可以调用本地设备API,并且,所开发的App还能使用原生UI控件。此外,通过MoSync IDE,开发者可以调用任何仿真器,包括本地平台的仿真器,及MoSync Reference Environment。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:980985次
积分:11556
积分:11556
排名:第823名
原创:234篇
转载:307篇
评论:149条
(1)(5)(12)(8)(6)(5)(4)(2)(14)(7)(9)(9)(6)(5)(4)(1)(4)(4)(5)(10)(8)(5)(6)(5)(7)(2)(24)(5)(2)(1)(5)(5)(7)(1)(1)(1)(5)(5)(2)(17)(1)(14)(4)(4)(1)(1)(10)(9)(7)(7)(5)(1)(5)(1)(7)(1)(3)(3)(4)(6)(3)(3)(1)(8)(6)(3)(53)(12)(2)(1)(3)(1)(1)(5)(1)(1)(1)(4)(15)(93)消灭Bug!十款免费移动应用测试框架推荐
发表于 18:12|
来源BestDesignTuts|
作者Andrew Smith
摘要:无论是iOS还是Android应用,各种Bug、终端测试都很让人头疼,而移动应用测试框架则可以帮助开发者简化测试流程,从而很好地解决这一问题。本文详细介绍了当下最受开发者喜爱的十款免费应用测试框架,快来看一看吧。
对于移动应用开发者而言,Bug往往是最让人头疼的一大问题。不同于时时刻刻可以修补的Web App,移动App中的Bug往往隐藏得很深,甚至有时候等到用户使用才显现出来,这么一来开发者搞不好就会赔了名声又折钱。所以在应用发行之前,对其进行严格的测试是非常必要的。而移动应用测试框架可以帮助开发者简化测试流程,从而很好地解决这一问题。对此,我们详细介绍了当下最受开发者欢迎的十大免费移动应用测试框架,一起来看看吧。1. (iOS/Android)Appium是一个开源的、跨平台的自动化测试工具,适用于测试原生或混合型移动App,支持iOS、Android和FirefoxOS平台。通过它,开发者可以利用测试代码完全访问后端API和数据库。Appium是基于无需SDK和编译就可以对原生应用进行测试的理念而设计的。该框架不仅能完美支持iOS、Android应用,还可直接在PHP、Python、Ruby、C#、 Clojure、Java、Objective-C、JavaScript及Perl等语言中编写测试脚本。2. (iOS/Android)Calabash是一款适用于iOS和Android平台的跨平台应用测试框架,支持Cucumber,开源且免费,隶属于Xamarin公司。通过Calabash,开发者可以对应用进行多方位测试,比如截屏、手势识别、实际功能代码等。3. (iOS)KIF的全称是Keep It Functional,来自Square,是一款专为iOS设计的移动应用测试框架。由于KIF是使用Objective-C语言编写的,因此,对于iOS开发者而言,用起来要更得心应手,可以称得上是一款非常值得收藏的iOS测试利器。4. (Android)Android开发者们注意了,这款测试框架一定会让你们兴奋不已,因为它是一款已基本上摆脱了模拟器测试的老套路的速率单元测试框架。Robolectric可以解压Android SDK,还能直接对应用进行测试,从而帮你轻而易举地解决所遇到的任何问题。5. (iOS)Gitorious是一个基于Git版本控制系统的Web项目托管平台,使用Ruby on Rails开发。而其移动测试框架(MTF)也是深受开发者欢迎,Gitorious移动测试框架是一款充分利用Sikuli自动化工具的iOS测试框架。Gitorious MTF能够利用截屏和Python脚本,进行细致入微的测试,并将测试结果返还给开发者以提高应用质量及修复漏洞。
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章深受开发者喜爱的10大Core Data工具和开源库
招聘信息:
本文由者飞扬翻译自Raywenderlich,敬请勘误。原文地址:在iOS和OSX应用程序中存储和查询数据,Core Data是一个很好的选择。它不仅可以减少内存使用、提高性能,而且它可以使你避免写很多不必要的样板文件代码。此外,Core Data API非常灵活,可以用在各种应用程序中,所有应用程序有不同的数据存数需求。然而,这种灵活性意味着有时Core Data用起来可能稍微有点困难。即便你是一个Core Data专家,仍然会需要处理一些平常的任务,也会有很多犯错的可能性。幸运的是,有很多很好的工具可以帮你解决问题,让Core Data更易于使用。为此我们选出了10个你应该知道和喜欢的工具和开源库。注意:即便有这些优秀的工具和库,你仍需要很好地理解Core Data。如果你需要获得Core Data的更多经验,下载查阅我们的新手教程。还要注意的是这篇文章以Objective-C为主,因为大部分Core Data库都是用Objective-C写的。如果你想学习怎样用Swift来使用Core Data,可下载查阅我们已经出版的书,这本书已经完全为iOS 8和Swift更新了!#10. RestKitRestKit是为了和RESTful web服务交互的一个Objective-C框架。它提供了一个Core Data实体映射引擎,把序列化的响应对象直接映射给托管的对象。下面的代码例子展示了如何设置RestKit来访问 ,同时把/weather端点的JSON响应映射成为一个WFWeather 托管对象。-&(void)loadForecastData&{
&&RKManagedObjectStore&*store&=&self.managedObjectS
&&RKEntityMapping&*mapping&=&[RKEntityMapping&mappingForEntityForName:@"WFWeather"
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&inManagedObjectStore:store];
&&[mapping&addAttributeMappingsFromArray:@[@"temp",&@"pressure",&@"humidity"]];
&&NSIndexSet&*statusCodeSet&=&RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
&&RKResponseDescriptor&*responseDescriptor&=&[RKResponseDescriptor
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&responseDescriptorWithMapping:mapping
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&method:RKRequestMethodGET
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&pathPattern:@"/data/2.5/weather"
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&keyPath:@"main"
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&statusCodes:statusCodeSet];
&&NSURL&*url&=&[NSURL&URLWithString:
&&&&&&&&&&&&&&&&[NSString&stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?q=Orlando"]];
&&NSURLRequest&*request&=&[NSURLRequest&requestWithURL:url];
&&RKManagedObjectRequestOperation&*operation&=&[[RKManagedObjectRequestOperation&alloc]
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&initWithRequest:request
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&responseDescriptors:@[responseDescriptor]];
&&operation.managedObjectCache&=&store.managedObjectC
&&operation.managedObjectContext&=&store.mainQueueManagedObjectC
&&[operation&setCompletionBlockWithSuccess:
&&&^(RKObjectRequestOperation&*operation,&RKMappingResult&*mappingResult){
&&&&&NSLog(@"%@",mappingResult.array);
&&&&&[self.tableView&reloadData];
&&&}&failure:^(RKObjectRequestOperation&*operation,&NSError&*error)&{
&&&&&NSLog(@"ERROR:&%@",&[error&localizedDescription]);
&&[operation&start];
}代码分解:1、首先,创建一个RKEntityMapping对象来告诉RestKit如何把API的响应映射给WFWeather属性。2、这里,RKResponseDescriptor 把上面从/data/2.5/weather到 RKEntityMapping 实例的响应联系在了一起。3、RKManagedObjectRequestOperation 定义了要执行的操作。这个例子中,你从OpenWeatherMap API请求了Orlando(奥兰多)的天气,然后把响应指向上面提到的RKResponseDescriptor 实例。4、最后,用需要的成功和失败的block(块)执行操作。当RestKit看到和定义的RKResponseDescriptor 想匹配的应答返回的时候,它将直接把数据映射到WFWeather 实例上。以上代码不需要手动JSON解析、检查[NSNull null]、手动创建Core Data实体,或者连接一个API时任何其他必须做的事情。RestKit通过一个简单的映射字典把API响应转换成Core Data模型对象。没有比这个更容易的了。要学习如何安装和使用RestKit,请下载查阅我们的 。#9. MMRecordMMRecord是一个基于block(块)的集成库,它使用Core Data模型配置,自动创建并填充来自API响应的完整地对象图。当它在后台为你创建、获取、填充NSManagedObjects 实例时,使从web服务请求来的生成的本地对象尽可能简单。它使得从web服务请求生成本地对象,像它在后台创建、获取、填充NSManagedObjects 实例那样简单。下面的代码块,展示了怎样使用MMRecord来进行相同的Orlando天气调用,以及你在上面的RestKit例子中做的数据映射:NSManagedObjectContext&*context&=&[[MMDataManager&sharedDataManager]&managedObjectContext];
[WFWeather&
&&startPagedRequestWithURN:@"data/2.5/weather?q=Orlando"
&&&&&&&&&&&&&&&&&&&&&&data:nil
&&&&&&&&&&&&&&&&&&&context:context
&&&&&&&&&&&&&&&&&&&&domain:self
&&resultBlock:^(NSArray&*weather,&ADNPageManager&*pageManager,&BOOL&*requestNextPage)&{
&&&&NSLog(@"Weather:&%@",&weather);
&&failureBlock:^(NSError&*error)&{
&&&&NSLog(@"%@",&[error&localizedDescription]);
}];无需编写任何复杂的网络代码,或者手动解析JSON响应,你已经调用一个API,并且已用几行代码的响应数据填充了Core Data托管对象。MMRecord 如何知道你在API响应中定位你的对象?你的托管对象必须是MMRecord 的子类,然后像下面所示那样重载keyPathForResponseObject :@interface&WFWeather&:&MMRecord
@property&(nonatomic)&float&
@property&(nonatomic)&float&
@property&(nonatomic)&float&
@implementation&WFWeather
+&(NSString&*)keyPathForResponseObject&{
&&&&return&@"main";
@endkeyPathForResponseObject 返回了一个关键路径,指定了来自API的响应对象的根相关的对象的位置。这个例子中,关键路径是data/2.5/weather&调用的main。神奇之处不止这一点-MMRecord要求你创建一个服务器类,这个类知道如何请求你集成的API。谢天谢地,MMRecord附带一个基于AFNetworking 的服务器类的例子。关于配置和使用MMRecord的信息,的说明文件是最好的开始。#8. Magical Record灵感来源于Ruby on Rails' ActiveRecord 系统,提供了一系列支持一行实体的获取、嵌入和删除操作的类和类别。下图是运行的MagicalRecord视图://&Fetching&NSArray&*people&=&[Person&MR_findAll];
//&Creating&Person&*myPerson&=&[Person&MR_createEntity];
//&Deleting&[myPerson&MR_deleteEntity];MagicalRecord让设置Core Data堆栈变得非常容易。而不是使用很多行的样板代码,你可以像下边这样只用AppDelegate文件里的一个方法调用来设置一个完整的Core Data堆栈。-&(BOOL)application:(UIApplication&*)application&didFinishLaunchingWithOptions:(NSDictionary&*)launchOptions&{
&&[MagicalRecord&setupCoreDataStackWithStoreNamed:@"ExampleDatabase.sqlite"];
&&return&YES;
}在application:didFinishLaunchingWithOptions: 里,用你SQLite文件的名调用setupCoreDataStackWithStoreNamed。 这就建立了NSPersistentStoreCoordinator、NSManagedObjectModel 和 NSManagedObjectContext 的实例,这样你就可以准备使用Core Data工作了。进一步地了解如何安装和使用MagicalRecord,请参看我们的。#7. GDCoreDataConcurrencyDebugging并发问题是在Core Data中调试最难的事情。performBlock API可以帮忙,但仍然很容易犯错。你可以将开源项目GDCoreDataConcurrencyDebugging添加到自己的项目中,当在错误线程或者调度队列上访问NSManagedObjects时,它通过控制台消息提醒你。以下是在错误环境中访问NSManagedObject 实例的例子:__block&NSManagedObject&*objectInContext1&=&
[context1&performBlockAndWait:^{
&&objectInContext1&=&[[NSManagedObject&alloc]&initWithEntity:entity&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&insertIntoManagedObjectContext:context1];
&&objectInContext1.name&=&@"test";
&&NSError&*saveE
&&if&([context1&save:&saveError]&==&NO)&{
&&&&NSLog(@"Error:&%@",&[saveError&localizedDescription]);
//&Invalid&access
[context2&performBlockAndWait:^{
&NSString&*name&=&objectInContext1.
}];在上面的代码中,你正尝试从一个对象中context2 读取name, 这个对象最初在context1 被创建。如果你使用GDCoreDataConcurrencyDebugging 运行上面的例子,你会看到下面的控制台消息,通知你有问题发生: 13:20:24.530 SampleApp[24222:60b] CoreData concurrency failure注意:在你的应用程序上传到App Store上去时,你得移除掉GDCoreDataConcurrencyDebugging ,它增加了少量的开销,那些开销无需存在于在发布的应用中。在iOS 8和OS X Yosemite中,Core Data现在有检测并发问题的能力。想要启用这个新功能,你可以在启动时通过Xcode?s Scheme Editor 把-com.apple.CoreData.ConcurrencyDebug 1 传给你的应用程序。然而,直到你逐步淘汰对OS更早版本的支持,GDCoreDataConcurrencyDebugging 都会在开发过程中一直通知你并发问题。 是安装和使用这个工具最好的资源信息。#6. CoreData-hsCoreData-hs 生成类别方法来执行Core Data模型里所有实体和属性的常见获取请求。创建这些方法不难,但它耗时--编码时节省每一点时间都是有价值的!比如,你的天气应用程序里有一个查看天气预报和使用带有timeStamp,temp和 summary 属性的WFForecast 实体来模仿每天的预报的视图,CoreData-hs 将为你创建以下的类别:#import&#import&@interface&WFForecast&(Fetcher)
+&(NSArray&*)summaryIsEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryIsLessThan:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryIsGreaterThan:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryIsGreaterThanOrEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryIsLessThanOrEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryIsNotEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryIsBetwixt:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsLessThan:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsGreaterThan:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsGreaterThanOrEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsLessThanOrEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsNotEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsBetwixt:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)timeStampIsEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)timeStampIsLessThan:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)timeStampIsGreaterThan:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)timeStampIsGreaterThanOrEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)timeStampIsLessThanOrEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)timeStampIsNotEqualTo:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)timeStampIsBetwixt:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryIsLike:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryContains:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryMatches:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryBeginsWith:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)summaryEndsWith:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempIsLike:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempContains:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempMatches:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempBeginsWith:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
+&(NSArray&*)tempEndsWith:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorB
@end正如你看到的,生成了很多方法!以下是tempIsGreaterThan:inContext:sortDescriptors: error: 生成的实现方法:+&(NSArray&*)tempIsGreaterThan:(id)object&inContext:(NSManagedObjectContext&*)context&sortDescriptors:(NSArray&*)sort&error:(void(^)(NSError&*error))errorBlock&{
&&NSFetchRequest&*fetchRequest&=&[NSFetchRequest&fetchRequestWithEntityName:@"WFForecast"];
&&[fetchRequest&setPredicate:[NSPredicate&predicateWithFormat:@"temp&>&%@",&object]];
&&[fetchRequest&setSortDescriptors:sort];
&&NSError&*err&=&
&&NSArray&*results&=&[context&executeFetchRequest:fetchRequest&error:&err];
&&if(!results&&&&errorBlock)&{
&&&&errorBlock(err);
&&&&return&
}方法一旦生成,你就可以用它们通过特定条件获取请求。比如,需要获取所有温度超过70°的WFForecast对象,你可以调用tempIsGreaterThan:inContext:sortDescriptors:error:,然后简单地传递目标温度,如下所示:NSSortDescriptor&*sortDescriptor&=&[NSSortDescriptor&sortDescriptorWithKey:@"temp"&ascending:YES];
NSArray&*results&=&[WFForecast&tempIsGreaterThan:@(70)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&inContext:self.managedObjectContext
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sortDescriptors:@[sortDescriptor]
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&error:^(NSError&*error)&{
&&NSLog(@"Error:&%@",&[error&localizedDescription]);
}];你将返回一个匹配对象的数据。CoreData-hs 是一个轻量级的工具,如果你倾向于手动生成大量这种类型的请求,它可以节省你的时间。关于安装和使用说明,请查阅。#5. Core Data Editor你可以在Core Data Editor的GUI中查看和编辑APP基于Core Data的数据模型,它支持XML、二进制和SQLite持久性存储类型。除了可以编辑基本属性,你还可以编辑和形象化数据关系。你也可以在使用Core Data Editor的同时使用Mogenerator工具 (第#2项中讨论)来创建模型代码。Core Data Editor熟悉苹果的模式,展示不带Z前缀的数据,如果你曾看到Core Data生成的SQL文件,这个前缀你可能会熟悉。你可以在一个不错的表格格式里浏览应用程序数据库里的内容。它也支持预览二进制数据,比如图片,以及用一个标准日期选择器在线编辑数据。如果你想创建一个种子文件或者只想导入数据,Core Data Editor可以生成一个CSV文件,把它转换成Core Data里持久化对象,如下所示:安装Core Data Editor,从下载免费试用版。解压下载的ZIP归档文件,把Core Data Editor.app 文件移动到你的Applications 目录里。这个应用的作者最近也把它了,如果你想了解它是如何工作的,以及提高自己,你可以去学习下。第一次启动应用程序,它会引导你完成一个简短的设置过程。这个过程是可选的,但如果你至少指定iPhone模拟器目录和Xcode归档数据的目录,它将会加快速度。注意:因为你得在GUI中选择导出的数据和模拟器目录,所以你可能在使用OS X Lion默认设置时会遇到问题,它会隐藏你的库文件夹。在Mavericks OS X里,你可以通过在Finder的主目录里,选择View / Show View Options ,检查Show Library Folder来纠正这个问题。在Lion和Mountain Lion OS X中,同样的事情可以通过在终端输入chflags nohidden ~/Library/ 来完成。更多有关Core Data的详情可以在这个网站上找到。#4. SQLite3有时当调试一个棘手的数据问题时,在底层的Core Data SQLite数据库中直接执行SQL查询是有帮助的。如果你没有扩展的数据库经验,这个可能不适合你。使用SQLite3,首先打开Terminal终端,并导航到你应用程序的Documents 目录。根据你的安装情况,Documents 目录类似于 ~/Library/Application Support/iPhone Simulator/7.1-64/Applications/{your app's ID}/Documents.更改上面命名中7.1-64 来匹配你使用的模拟器的版本。{your app's ID} 由Xcode自动生成,并唯一地标识应用的安装。没有简单的办法找出哪个ID是你的。你可以在创建Core Data堆栈的时候添加日志记录,也可以寻找最近被多次修改的目录--这将是你当前工作的应用程序。文档目录将包含一个扩展sqlite的文件,这个就是你应用程序的数据库文件。对于使用苹果Core Data模板的应用程序而言,文件名称要匹配你的应用的名字。用如下所示的SQLite3程序打开这个文件(这里的例子应用叫AddressBook,你的文件名字会有所不同):$&sqlite3&AddressBook.sqlite你将在控制台看到以下提示:SQLite&version&3.7.13&&17:46:21
Enter&".help"&for&instructions
Enter&SQL&statements&terminated&with&a&";"
sqlite>现在准备好对数据库执行标准的SQL查询。比如,为了看到Core Data 使用的模式,可执行以下的命令:sqlite>&select&*&from&sqlite_SQLite用模式里的一个文本列表清单来响应你的查询,如下所示:table|ZMDMPERSON|ZMDMPERSON|3|CREATE&TABLE&ZMDMPERSON&(&Z_PK&INTEGER&PRIMARY&KEY,&Z_ENT&INTEGER,&Z_OPT&INTEGER,&ZISNEW&INTEGER,&ZFIRSTNAME&VARCHAR&)
table|Z_PRIMARYKEY|Z_PRIMARYKEY|4|CREATE&TABLE&Z_PRIMARYKEY&(Z_ENT&INTEGER&PRIMARY&KEY,&Z_NAME&VARCHAR,&Z_SUPER&INTEGER,&Z_MAX&INTEGER)&table|Z_METADATA|Z_METADATA|5|CREATE&TABLE&Z_METADATA&(Z_VERSION&INTEGER&PRIMARY&KEY,&Z_UUID&VARCHAR(255),&Z_PLIST&BLOB)
sqlite>所有在列表栏里的Z前缀是Core Data底层使用SQLite的一部分。出于分析的目的,可以忽略它们。注意:你不能直接写入SQLite Core Data数据库。苹果可以随时修改底层结构。如果你真的有需要在生产应用程序中直接操作SQLite数据,你应该放弃Core Data,用原始的SQL访问。有几种流行的框架可以帮助你管理你应用中的SQL实现,包括B和 。如果只是分析数据,到处访问SQLite数据库文件是没什么关系的--只要不修改它的内容。直接使用SQL分析数据的一个例子是不同属性进行分组和计算,以理解属性的差异。举个例子,如果你有一个地址薄的应用例子,想知道在每个城市里有多少联系人生活,你可以用SQLite3提示执行以下命令:SELECT&t0.ZCITY,&COUNT(&t0.ZCITY&)&FROM&ZMDMPERSON&t0&GROUP&BY&t0.ZCITYSQLite会用地址薄数据库里每个不同城市的数据来作出响应,如下面的例子所示:San&Diego|23
Orlando|34
Houston|21退出SQLite3终端程序,简单地执行以下的命令:sqlite>&.exit想要了解更多SQLite3的信息,可打开终端查看man 页,并执行man sqlite3命令。#3. MDMCoreDataMDMCoreData(免责声明--这个库是我的写的!)是一个开源类的集合,让使用Core Data变得更简单。它并不试图隐藏或抽象Core Data,而是执行最佳实践,以及减少所要的模板代码。这比Xcode Core Data模板是一个更好的选择。MDMCoreData由以下四个类组成:MDMPersistenceController,一个便利的控制器,支持创建多个child-managed object context 来建立一个高效的Core Data堆栈。它有一个内置的私有 managed object context,异步保存到SQLite仓库。MDMFetchedResultsTableDataSource,获取ResultsController delegate和列表数据源。MDMFetchedResultsCollectionDataSource,获取ResultsController delegate和集合数据源。NSManagedObject+MDMCoreDataAdditions,一个托管对象类别,它提供辅助方法来消除模板代码,比如实体名。MDMCoreData一个最大的特点是,它伴随着一个支持表数据源的Core Data--所以你不必担心要自己去实现。你可以只设置MDMFetchedResultsTableDataSource实例的表数据源,而不是实现UITableViewDataSource 和NSFetchedResultsControllerDelegate 协议需要的所有方法。当实例化MDMFetchedResultsTableDataSource 对象,你只要简单地在表视图里简单传送,并获取一个results controller:-&(void)viewDidLoad&{
&&[super&viewDidLoad];
&&self.tableDataSource&=&[[MDMFetchedResultsTableDataSource&alloc]&initWithTableView:self.tableView
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fetchedResultsController:[self&fetchedResultsController]];
&&self.tableDataSource.delegate&=&
&&self.tableDataSource.reuseIdentifier&=&@"WeatherForecastCell";
&&self.tableView.dataSource&=&self.tableDataS
}MDMFetchedResultsTableDataSource 有一个代理,有两个必须实现的方法。一个方法为你的表格配置cell:-&(void)dataSource:(MDMFetchedResultsTableDataSource&*)dataSource&&&&&&configureCell:(id)cell
withObject:(id)object&{
OWMForecast&*forecast&=&
UITableViewCell&*tableCell&=&(UITableViewCell&*)&&&tableCell.textLabel.text&=&forecast.&&&tableCell.detailTextLabel.text&=&forecast.
}第二个方法处理删除操作:-&(void)dataSource:(MDMFetchedResultsTableDataSource&*)dataSource&&&&&&&deleteObject:(id)object
atIndexPath:(NSIndexPath&*)indexPath&{
[self.persistenceController.managedObjectContext&deleteObject:object];
}实现两个所需的MDMFetchedResultsTableDataSource 方法,远比实现表数据源所有所需方法和获取results controller protocols要简单的多。你可以在 找到更多关于MDMCoreData的信息。#2. Mogenerator因为Core Data完全支持键/值编码(KVC)和键/值观察(KVO),就没必要实现自定义的NSManagedObject 类。当对你读写实体时,可以使用setValue:forKey: 和setValue:forKey: 。但这往往变得复杂和难于调试,因为字符串在编译的时候没法检查正确性。比如,你有个person 的Core Data实体,你可以像这样读写属性:NSString&*personName&=&[person&valueForKey:@"firstName"];
[person&setValue:@"Ned"&forKey:@"firstName"];上面的person 对象是一个属性名为firstName 的NSManagedObject 实例。想要读取firstName,你得用firstName 作为valueForKey:关键字。类似地,你可以使用setValue:forKey: 设置一个person 对象的first name。更好的方法就是使用标准的访问方法或者点语法。然而,要这么做的话你必须为你的实体实现NSManagedObject一个自定义子类。你可以添加逻辑模型,比如获取请求和验证。你可能使用Xcode的Create NSManagedObjectSubclass功能快速创建单个实体的子类。虽然是个捷径,但如果你的数据模型比较大,它会增加额外的开销,会在更改模型时带来许多问题。重新创建子类意味着清除你所有的自定义模型逻辑--这就意味着你应该在自定义模型以外创建逻辑。它适合于创建带有托管对象属性和自定义模型逻辑类别的自定义子类的常规模式。命令行工具Mogenerator 会自动化这些精确的任务。每个Core Data实体会生成两个类。第一个类是为机器消耗生成的,当模型改变的时候不断地被覆盖。第二个类是为你所有的自定义逻辑生成的,从来不被覆盖。Mogenerator 有一系列其他好处,包括以下几点:读/写数值型属性时无需使用NSNumber 对象。处理设置的辅助方法创建新实体的辅助方法一个实体识别的方法Mogenerator可以从上可用的DMG文件来安装,或者通过Homebrew安装Mogenerator,打开终端,执行下面的命令:brew&install&mogenerator一旦安装,用cd 命令来改变你应用程序的目录,然后从终端运行Mogenerator,像这样:$&mogenerator&-m&MySampleApp/ExampleModel.xcdatamodeld&-O&MySampleApp/Model&--template-var&arc=true在上面的命令中,你可以用-m 选项调用Mogenerator,紧随其后的是模型的位置。你也可以用-O 选项指定生成类的位置。当使用ARC时,你需要传递--template-var arc=true 选项。你可以让Xcode通过创建Run Script Build Phase来运行Mogenerator。Build Phases是编译期间Xcode必须执行的任务的描述。要添加一个Build Phase,首先选择target,选择Build Phases标签,然后选择菜单里的Editor / Add Build Phase / Add Run Script Build Phase 。在新Run Script下的Shell脚本文本区域里添加以下代码,确保修改mogenerator 的参数,来适配你的工程:if&[&"${CONFIGURATION}"&==&"Debug"&];&then
echo&"Running&Mogenerator"
mogenerator&-m&MySampleApp/ExampleModel.xcdatamodeld&-O&MySampleApp/Model&--template-var&arc=true
echo&"Finished&Mogenerator"
else&echo&"Skipping&Mogenerator"
fi以上的运行脚本,会在你每次运行一个调试编译命令时让Xcode运行Mogenerator。如果模型没什么改动的话,Mogenerator将什么都不做,然后退出。为了快速生成子类,现在你已经把Mogenerator合并到你的工作流中,你应该好好利用它的其它特性。比如,不用每次打开原始值,你只要给它们添加Value后缀, 如以下的代码片段所示://&Without&Mogenerator
if&([person.isFriend&boolValue])&{
&&//&Do&some&work
//&With&Mogenerator
if&(person.isFriendValue)&{
&&//&Do&some&work
}因为在Core Data里bool 类型是以NSNumber 类型存储的,在检查值是否为真之前你必须调用person 对象的boolValue 。通过Mogenerator,就不需要额外的步骤了,因为你只要简单地调用 isFriendValue即可。如果Mogenerator对你的工具箱来说看起来像个有用的补充,你可以在 找到更多有关Mogenerator的信息。#1. InstrumentsInstruments 是OS X 和 iOS里为研究几乎所有性能和内存问题的重要工具--包括Core Data 问题。清单里的其它工具提供了许多自动化和便捷性,但Instruments通常会是研究任何问题或者性能调整的第一站。下图是Time Profiler 和Core Data 模板,对Core Data配置来说是最有用的。默认的Core Data 模板,添加了可选的Faults Instrument功能,通过提供以下功能来帮你调整和监控应用程序的性能:Core Data Fetches Instrument,捕捉获取次数和获取操作的持续时间。Core Data Cache Misses Instrument,捕捉导致缓存遗漏的故障事件。Core Data Saves Instrument,捕捉托管对象上下文环境保存事件的信息。Core Data Faults Instrument,捕捉NSManagedObjects 或相关关系的延迟初始化过程发生的故障事件的信息。这个是Core Data应用程序中典型的instruments profile。你可以看到获取请求何时发生,以及请求所花时间,保存操作何时以及如何发生,以及何时出现故障灯。要获取更多有关Instruments的信息,请下载我们的教程:。下一步Core Data是个很强大的框架,但它会有很多开发消耗,不过这篇文章中的工具和库提供了一些方法来高效、有效地帮你解决消耗问题。作者:Matthew Morey()Matthew Morey 是一位综合工程师、开发者、黑客以及创造者的多面手。作为iOS论坛里的一名活跃分子,以及里的移动项目的主管,他已经领导了全球许多成功的移动项目。他是的创造者,专门适用于水上运动爱好者的一个海洋条件下的应用程序;以及,这个应用可以让你用智能手表控制无线演示。在不进行开发的时候,他喜欢旅行,滑雪和冲浪。他有关技术和商务的博客地址是 。
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量16272点击量10875点击量8664点击量8017点击量7488点击量7063点击量6588点击量6497点击量5716
&2016 Chukong Technologies,Inc.
京公网安备89

我要回帖

更多关于 单页应用框架 的文章

 

随机推荐