CS193P第九堂课摘要及心得笔记

CS193P第九堂课摘要及心得笔记

 

在深度探讨完 iPhone 基本的 MVC 架构后,接下来的课程内容将转向 Cocoa Touch 中各式各样不同的 API,以便解决我们开发上的各种问题,并且增加程式的多样度。而在这一次的课程内容中,将主要谈 iPhone 中的资料读取以及储存方法,还有网路上的资料存取,请多多指教!

Property List

在所有的资料储存办法当中,最容易的莫过于 Property List 了,阵列、字典、字串和资料都可以存成 XML 格式的 Property List,事实上,我们之前所用到的 NSUserDefaults 就是一个 Property List。

然而,并非所有的资料都是适合用它来储存,像是过多的资料或是自己设计的一些複杂物件都不太适合,因为 Property List 会一次将整个文件内容读到记忆体中,不管是效率或是空间上都不是很理想。

至于实际的使用方式,则是搭配 NSArray 或是 NSDictionary 来使用,配合以下几个方法:

// 写入 - writeToFile:aPath atomically:flag; - writeToURL:aURL atomically:flag; // 读取 - initWithContentsOfFile:aPath; - initWithContentsOfURL:aURL;

关于 Property List 的更多细节,有兴趣的读者可以参考 Property List Programming Guide for Cocoa,里面有详细的说明。

iPhone 的档案系统

因为安全性的因素,在 iPhone OS 下,每一个软体的档案以及资料夹都是被独立隔开的,而每一个软体可以读取、写入的档案系统,大概可以用下列的结构显示:

  • Documents
  • Library
  • 以上这些资料,大多都会在 iTunes 同步时备份起来,而那我们要如何取得这些资料夹的路径呢?请参考以下方法:

    // 基本的目录 NSString *homePath = NSHomeDirectory; // 根目录 NSString *tmpPath = NSTemporaryDirectory; // 暂存目录 // Documents 资料夹 NSArray *paths = NSSearchPathForDirectoriesInDomains ; NSString *documentsPath = [paths objectAtIndex:0]; // < 程式根目录>/Documents/foo.plist NSString *fooPath = [documentsPath stringByAppendingPathComponent:@“foo.plist”];

    值得注意的是,我们可能会想在程式的软体中预先搭载一些档案,这些档案会存在.app 的资料夹中。但这些资料夹 read-only 的,所以若是这些资料要拿来修改并且做纪录的话,可要记得先将档案複製到 Documents 资料夹下,再进行后续的动作。

    Archiving Object

    就如同 Property List 一般,透过 Archiving Object 的技巧,我们可以将任何一个物件存到档案系统中,当然也可以读取。为了让我们自订的类别能够储存为 Archiving Objects,我们需要让物件实做 NSCoding 这个 Protocol:

    // 将物件编码 - encodeWithCoder:coder {   [super encodeWithCoder:coder];   [coder encodeObject:name forKey:@“Name”];   [coder encodeInteger:numberOfSides forKey:@“Sides”]; } // 从档案中解码 - initWithCoder:coder {   self = [super initWithCoder:coder];   name = [[coder decodeObjectForKey:@“Name”] retain];   numberOfSides = [coder decodeIntegerForKey:@“Side”]; }

    而当我们要将物件储存、读取时,只需要呼叫下列方法:

    BOOL result = [NSKeyedArchiver archiveRootObject:polygons toFile:path]; // 储存 NSArray polygons = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; // 读取

    是不是很容易呢?更进一步的资讯还请参考 Archives and Serializations Programming Guide for Cocoa,相信一定会有收穫的。

    SQLite

    SQLite 是一个轻量级的 SQL 资料库,整个资料库就是一个档案,并且使用标準的 SQL 语法来纯取资料,相当的方便有效率。而在 iPhone 的平台上就内建了 SQLite 的支援,使用方法如下:

    // 开启资料库 int sqlite3_open; // 执行 SQL 指令 int sqlite3_exec, void *context, char **error); // 自订的 Callback 函式 int callback; // 关闭资料库 int sqlite3_close;

    更详细的使用方式,请参考 SQLite in 5 Minutes Or Less 和 Intro to the SQLite C Interface。

    Core Data

    Core Data 是在 iPhone OS 3.0 后所新增的功能,是高阶抽象化的物件储存管理系统,我们可以使用 NSPredicate 和 NSEntityDescription 两个类别来代替複杂的 SQL 指令,详细的使用方式可以参考 Core Data Tutorial for iPhone OS。

    XML

    在 iPhone 平台上,要处理 XML 的资料格式可以透过 libxml2 或是 NSXMLParser,前者是 Unix 下面常见的 Open Source 函式库,主要是透过 Event-Driven 的方式进行 parse。而后者是高阶抽象过的 API,较为容易使用,但功能比较没有那幺强大。就笔者自己的心得,如果只是要 parse RSS feeds,透过 NSXMLParser 就可以有很好的效果了。

    请参考 libxml2 + xmlTextReader on Macs 和 Parsing XML in Cocoa,两者的内容都相当实用。

    JSON

    相信对于本部落格的读者来说,JSON 应该是个相当熟悉的格式,也就是 JavaScript 中常用的资料格式,就如同 Property List 一般的容易使用。虽然在 iPhone 中并没有内建 JSON 的支援,但我们可以在网路上找到一个 Objective-C 的 JSON Framework,在许多 iPhone 应用程式中都被广泛的使用。

    推播通知
    CS193P第九堂课摘要及心得笔记
    由于 iPhone OS 的先天限制,我们开发者没办自行设计在背景执行的程式,当使用者关闭应用程式之后,我们就没被法传送新的资料到使用者的 iPhone 上了。然而,这件事情在 OS 3.0 后产生了变化,因为 Apple 推出了推播通知的 Framework,让我们能够随时传送文字讯息并且播放音讯提醒使用者。而这样的作法除了省电之外,也可以大幅减少网路的流量。

    而要使用这项服务,我们必须自行架设主机,然后在需要更新资讯时通知 Apple 的 Push Notification Server,由 Apple 的 Server 统一将资讯推播到使用者的 iPhone 中。大概的流程如下:

    1. 程式向 iPhone 提出推播的要求
    2. iPhone 通知 Apple Push Service 将使用此程式的推播,并取得 Token
    3. iPhone 将 Token 传给开发者的 Server

    而当我们需要传送资讯时,开发者则传送 JSON 并且内含 Token 给 Apple Push Service,而 Apple 就会将我们的资讯转达给使用者的 iPhone 了。详细的範例程式,大家可以参考投影片 59 到 75 页,里面有上述每一个步骤的详细说明。

    结论

    在这一次的课程内容中,我们学习到了在 iPhone 中的各种五花八门的档案操作方法。在下一次的课程中,我们将讨论 iPhone 应用程式的效能优化方法,包含多执行绪的使用以及远端档案操作的技巧,还请拭目以待!

    参考资源
    上一篇: 下一篇: