Cocoa学习

我的Cocoa/Cocoa Touch学习笔记

iOS项目的测试简介

记得有人说过,写不写测试代码是判断一个开发者是否成熟的标志。良好的测试代码能够让程序代码更健壮,使重构更加方便。虽然Objective-C是一种编译语言,但是在Xcode的帮助下,做测试和测试驱动开发(Test Driven Development, TDD)也非常方便。苹果官方有一个关于如何做为项目增加测试支持的文档,不过iOS 4.3的文档包的的该文档已经比较老了,如果你是付费iOS开发者,那么可以看看iOS 5.0的文档包的的该文档,已经更新为Xcode 4的教程了。

iOS的测试分两种,一种是逻辑测试(Logic Tests);另一种是程序测试(Application Tests)。逻辑测试主要是用来测试模块的业务逻辑的;程序测试则是测试模块在整个应用程序中的行为是否正确。逻辑测试类似单元测试;而程序测试则类似集成测试。个人感觉,逻辑测试比较适合测试模型代码;而应用程序测试则比较适合测试控制器和视图代码,考虑到视图在iOS开发中主要是通过Interface Builder来实现,因此,应用测试实际上就是测试控制器代码的。

下面,简单的讲一下如何设置项目支持单元测试。我们要在Xcode中为项目建立两种测试的Target。

让iOS App通过iTunes进行文件交换

有一些App需要通过使用iTunes让用户上传和下载文档。要让iOS程序支持iTunes文件交换其实很简单,只需要在程序的Info.plist里增加一个键:UIFileSharingEnabled(Application supports iTunes file sharing),赋值YES

这样,编译之后进行机上运行的时候,连接设备到iTunes,就能进行文件交换了。

在程序中动态设置是否显示Dock图标

关于如何隐藏Dock图标的方法,相信大家都知道——即使没有没有编程经验的老用户都知道。那就是,在Application Bundle里的Info.plist中增加一个LSUIElement的键,设置值为YES。但是,在程序中往往要让用户选择是否启用或禁用Dock图标。而程序是不能修改Application Bundle里的Info.plist的,因为这样会破坏程序的数字签名,所以只能在程序代码中动态的设置Dock图标的状态。

其实动态设置Dock图标的方法很简单严格的说只有两行代码:

1
2
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);

在设置隐藏Dock图标的时候需要重启应用程序,无法在运行时动态完成的,而在显示Dock图标的时候则不需要。我做了一个简单的Demo程序。放到了Github上,有兴趣的可以看看。(以后在这里出现的其他示例代码也会放到那里。)

程序很简单,就一个复选框,用来设置是否显示Dock图标。通过一个-toggleDockIcon:方法来设置是否显示Dock图标。并且在-applicationDidFinishLaunching:方法,设置在程序初始化的时候是否需要显示Dock图标。主要代码如下:

在iOS上用Quartz绘制圆角矩形

Bezels是Mac OS X下,苹果私有的UI控件,用来提示用户某些信息。不过iOS下,就有很多第三方的Bezels风格的提示控件实现了。相信大家也见过很多了。下图左侧是OSX的提示音量变化的Bezels,右侧是iOS上的Bezels风格的进度提示。

在iOS上做Bezels的思路很简单,无非就是在UIView里绘制一个半透明的圆角矩形,然后加入其他的SubView。因为没有现成的绘制圆角矩形的API可用,所以我们来自己绘制一个——反正是为了学习嘛。

新建项目,添加一个UIView的子类,修改drawRect方法,如下:

iOS 5的Geocoding

很明显,本文有标题党的嫌疑。其实本文要说的是“iPhone Programming: The Big Nerd Ranch Guide”一书中第5章里的Whereami的例子。我照着书本做下来,但是感觉例子似乎有点问题。可能是我看书不仔细,不过这个例子要实现的功能很诡异——定位自己,然后自己用文本框加上一个Annotation(?)这太诡异了吧。

我现在对这个例子小做修改,那就是,在文本框中输入任何地址字符串,然后地图自动定位到该位置——类似Google Map的搜索。我基于书本上的代码,做一些小修改。

首先,注释掉-locationManager:didUpdateToLocation:fromLocation:这个方法里的所有代码。主要对-findLocation方法作出修改,实现地图搜索功能。

再谈NSAttributedString转HTML

我之前曾经写过一篇关于NSAttributedString转HTML的文章,因为没有得到理想的结果,而TextEdit的另存为HTML却非常漂亮,所以对此我一直耿耿于怀。今天又研究了一下TextEdit将文档另存为HTML的方法,总算能把这个问题画上一个圆满的句号了。

在来回翻阅了TextEdit的源码后,我发现在Document.m里的- (id)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError方法,就是苹果官方将NSAttributedString转HTML的方法(这个方法当然也包含了将富文本转成其他格式的方法,在此不详述了)。仔细阅读了这个方法之后,我发现原来苹果也是用的我在之前那篇文章中用到的那个方法:- (NSData *)dataFromRange:(NSRange)range documentAttributes:(NSDictionary *)dict error:(NSError **)error转的——我没把重点弄错。不错我的错误是错在调用的时候,设置的参数有问题。 下面贴上源码,在注释了进行解释: