原文地址:iPhone OS编程指南(一)作者:若水一叶

介绍

请注意:本文档之前命名为iPhone OS编程指南

iPhoneSDK为创建iPhone的本地应用程序提供必需的工具和资源。在用户的Home屏幕上,iPhone的本地应用程序表示为图标。它们和运行在Safari内部的web应用程序不同,在基于iPhoneOS的设备上,它们作为独立的执行程序来运行。本地应用程序可以访问iPhone和iPodTouch的所有特性,比如加速计、位置服务、和多点触摸接口,正是这些特性使设备变得更加有趣。本地应用程序还可以将数据保存在本地的文件系统中,甚至可以通过定制的URL类型来和安装在设备上的其它程序进行通讯。

为iPhone OS开发本地应用程序需要使用UIKit框架。利用该框架提供的基础设施和缺省行为,您可以在几分钟内创建一个具有一定功能的应用程序。UIKit框架(和系统中的其它框架)不但提供大量的缺省行为,而且提供了一些挂钩,开发者可以通过这些挂钩来定制和扩展它的行为。

谁应该阅读本文?

本文的目标读者是希望创建iPhone本地应用程序的新老iPhoneOS开发者,目的是向您介绍iPhone应用程序的架构,展示UIKit和其它重要系统框架中的一些关键的定制点。在介绍这些内容的同时,本文还将提供一些有助于正确设计的指导意见。文中还指出一些为特定主题提供建议和进行进一步讨论的其它文档。

虽然本文描述的很多框架也存在于Mac OS X系统中,但阅读本文并不需要熟悉Mac OS X及其技术。

先决条件

在开始阅读本文之前,您必须至少对下面这些Cocoa概念有基本的理解:

  • 有关Xcode和Interface Builder的基本信息及其在应用程序开发中的作用。

  • 如何定义新的 Objective-C类。

  • 如何管理内存包括如何创建和释放Objective-C对象。

  • 委托对象在管理应用程序行为中的作用。

  • 目标-动作范式在用户界面管理中的作用。

不熟悉Cocoa和Objective-C的开发者可以在Cocoa基本原理指南中得到相应的信息。

iPhone应用程序的开发需要在运行Mac OS Xv10.5或更高版本系统以及基于Intel的Macintosh电脑上进行,还必须下载和安装iPhoneSDK。有关如何得到iPhone SDK的信息,请访问http://www.apple.com.cn/developer/iphone/网站。

本文的组织

本文有如下章节:

  • “核心应用程序” 描述iPhone应用程序的基本结构,介绍一些所有应用程序都需要做好处理准备的关键任务。

  • “窗口和视图” 描述iPhone的窗口管理模型,展示如何通过视图来组织用户界面。

  • “事件处理” 描述iPhone事件处理模型,展示如何处理多点触摸和运动事件,以及如何在应用程序中使用拷贝和粘贴操作。

  • “图形和描画” 描述iPhoneOS的图形架构,展示如何描画各种形状和图像,以及如何在使用动画。

  • “文本和Web” 描述iPhoneOS的文本支持,介绍一些管理系统键盘的实例。

  • “文件和网络” 为如何操作文件和网络连接提供一些指导原则。

  • “多媒体支持” 展示如何使用iPhoneOS中的音频和视频技术。

  • “设备支持” 展示如何使用外接配件接口、位置服务、加速计、和内置的照相机接口。

  • “应用程序的偏好设置” 展示如何配置应用程序的偏好设置及如何将这些设置显示在Settings应用程序中。

提供反馈

如果您对本文有什么反馈,可以通过每个页面下方的内置反馈表进行反映。

如果您发现苹果软件或文档存在问题,我们鼓励您报告给苹果公司。如果您希望某个产品或文档在将来有所改变,则可以提交功能增强报告,具体做法是访问ADC网站上的缺陷报告(BugReporting)页面并提交报告,其URL如下:

http://developer.apple.com/bugreporter/

您必须有正当的ADC登录名和密码才能提交报告。按照缺陷报告页面上的指令进行操作就可以免费得到一个登录名。

相关信息

下面的文档中包含一些重要的信息,所有的开发者在开发iPhone OS的应用程序之前都应该加以阅读:

  • iPhone开发指南 从工具的角度描述iPhone开发过程中的一些重要信息,介绍如何配置设备及如何使用Xcode(和其它工具)连编、运行、和测试您的软件。

  • Cocoa基本原理指南 介绍iPhone应用程序开发中使用的设计模式以及其它与实践相关的信息。

  • iPhone人机界面指南 就如何设计iPhone应用程序的用户界面提供指导和重要信息。

下面的框架参考和概念性文档提供一些与iPhone关键主题相关的信息:

  • UIKit框架参考Foundation框架参考 为本文讨论的类提供参考信息。

  • iPhoneOS的视图控制其编程指南 讨论如何在iPhone应用程序界面中使用视图控制器。

  • iPhoneOS的表视图编程指南 介绍如何使用表视图,表视图在iPhone应用程序中经常被使用。

  • Objective-C2.0编程语言 介绍Objective-C和Objective-C运行系统,它们是iPhoneOS的很多动态行为及扩展性的基础。

核心应用程序

所有的iPhone应用程序都是基于UIKit框架构建而成的,因此,它们在本质上具有相同的核心架构。UIKit负责提供运行应用程序和协调用户输入及屏幕显示所需要的关键对象。应用程序之间不同的地方在于如何配置缺省对象,以及如何通过定制对象来添加用户界面和行为。

虽然应用程序的界面和基本行为的定制发生在定制代码的内部,但是,还有很多定制需要在应用程序的最高级别上进行。这些高级的定制会影响应用程序和系统、以及和设备上的其它程序之间的交互方式,因此,理解何时需要定制、何时缺省行为就已经足够是很重要的。本章将概要介绍核心应用程序架构和高级别的定制点,帮助您确定什么时候应该定制,什么时候应该使用缺省的行为。

核心应用程序架构

从应用程序启动到退出的过程中,UIKit框架负责管理大部分关键的基础设施。iPhone应用程序不断地从系统接收事件,而且必须响应那些事件。接收事件是UIApplication对象的工作,但是,响应事件则需要您的定制代码来处理。为了理解事件响应需要在哪里进行,我们有必要对iPhone应用程序的整个生命周期和事件周期有一些理解。本文的下面部分将描述这些周期,同时还对iPhone应用程序开发过程中使用的一些关键设计模式进行总结。

应用程序的生命周期

应用程序的生命周期是由发生在程序启动到终止期间的一序列事件构成的。在iPhoneOS中,用户可以通过轻点Home屏幕上的图标来启动应用程序。在轻点图标之后的不久,系统就会显示一个过渡图形,然后调用相应的main函数来启动应用程序。从这个点之后,大量的初始化工作就会交给UIKit,由它装载应用程序的用户界面和准备事件循环。在事件循环过程中,UIKit会将事件分发给您的定制对象及响应应用程序发出的命令。当用户进行退出应用程序的操作时,UIKit会通知应用程序,并开始应用程序的终止过程。

图1-1显示了一个简化了的iPhone应用程序生命周期。这个框图展示了发生在应用程序启动到退出过程中的事件序列。在应用程序初始化和终止的时候,UIKit会向应用程序委托对象发送特定的消息,使其知道正在发生的事件。在事件循环中,UIKit将事件派发给应用程序的定制事件处理器。有关初始化和终止事件的如何处理的信息,将在随后的“初始化和终止”部分进行讨论;事件处理的过程则在“事件处理周期”部分介绍,在后面的章节也还有更为详细的讨论。

图1-1  应用程序的生命周期

主函数

在iPhone的应用程序中,main函数仅在最小程度上被使用,应用程序运行所需的大多数实际工作由UIApplicationMain函数来处理。因此,当您在Xcode中开始一个新的应用程序工程时,每个工程模板都会提供一个main函数的标准实现,该实现和“处理关键的应用程序任务”部分提供的实现是一样的。main例程只做三件事:创建一个自动释放池,调用UIApplicationMain函数,以及使用自动释放池。除了少数的例外,您永远不应该改变这个函数的实现。

程序清单1-1  iPhone应用程序的main函数

#import <UIKit/UIKit.h>

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

请注意:自动释放池用于内存管理,它是Cocoa的一种机制,用于延缓释放具有一定功能的代码块中创建的对象。有关自动释放池的更多信息,请参见Cocoa内存管理编程指南;如果需要了解与自动释放池有关的具体内存管理规则,则请参见“恰当地分配内存”部分。

程序清单的核心代码是UIApplicationMain函数,它接收四个参数,并将它们用于初始化应用程序。传递给该函数的缺省值并不需要修改,但是它们对于应用程序启动的作用还是值得解释一下。除了传给main函数的argcargv之外,该函数还需要两个字符串参数,用于标识应用程序的首要类(即应用程序对象所属的类)和应用程序委托类。如果首要类字符串的值为nil,UIKit就缺省使用UIApplication类;如果应用程序委托类为nil,UIKit就会将应用程序主nib文件(针对通过Xcode模板创建的应用程序)中的某个对象假定为应用程序的委托对象。如果您将这些参数设置为非nil值,则在应用程序启动时,UIApplicationMain函数会创建一个与传入值相对应的类实例,并将它用于既定的目的。因此,如果您的应用程序使用了UIApplication类的定制子类(这种做法是不推荐的,但确实是可能的),就需要在第三个参数指定该定制类的类名。

应用程序的委托

监控应用程序的高级行为是应用程序委托对象的责任,而应用程序委托对象是您提供的定制类实例。委托是一种避免对复杂的UIKit对象(比如缺省的UIApplication对象)进行子类化的机制。在这种机制下,您可以不进行子类化和方法重载,而是将自己的定制代码放到委托对象中,从而避免对复杂对象进行修改。当您感兴趣的事件发生时,复杂对象会将消息发送给您定制的委托对象。您可以通过这种“挂钩”执行自己的定制代码,实现需要的行为。

重要提示:委托模式的目的是使您在创建应用程序的时候省时省力,因此是非常重要的设计模式。如果您需要概要了解iPhone应用程序中使用的重要设计模式,请参见“基本设计模式”部分;如果需要对委托和其它UIKit设计模式的详细描述,则请参见Cocoa基本原理指南部分。

应用程序的委托对象负责处理几个关键的系统消息。每个iPhone应用程序都必须有应用程序委托对象,它可以是您希望的任何类的实例,但需要遵循UIApplicationDelegate协议,该协议的方法定义了应用程序生命周期中的某些挂钩,您可以通过这些方法来实现定制的行为。虽然您不需要实现所有的方法,但是每个应用程序委托都应该实现“处理关键的应用程序任务”部分中描述的方法。

有关UIApplicationDelegate协议方法的更多信息请参见UIApplicationDelegate协议参考

主Nib文件

初始化的另一个任务是装载应用程序的主nib文件。如果应用程序的信息属性列表(Info.plist)文件中含有NSMainNibFile键,则作为初始化过程的一个部分,UIApplication对象会装载该键指定的nib文件。主nib文件是唯一一个自动装载的nib文件,其它的nib文件可以在稍后根据需要进行装载。

Nib文件是基于磁盘的资源文件,用于存储一或多个对象的快照。iPhone应用程序的主nib文件通常包含一个窗口对象和一个应用程序委托对象,还可能包含一个或多个管理窗口的其它重要对象。装载一个nib文件会使该文件中的对象被重新构造,从而将每个对象的磁盘表示转化为应用程序可以操作的内存对象。从nib文件中装载的对象和通过编程方式创建的对象之间没有区别。然而,对于用户界面而言,以图形的方式(使用InterfaceBuilder程序)创建与用户界面相关联的对象并将它们存储在nib文件中通常比以编程的方式进行创建更加方便。

有关nib文件及其在iPhone应用程序中如何使用的更多信息,请参见“Nib文件”部分,有关如何为应用程序指定主nib文件的信息则请参见“信息属性列表”部分。

事件处理周期

在应用程序初始化之后,UIApplicationMain函数就会启动管理应用程序事件和描画周期的基础组件,如图1-2所示。在用户和设备进行交互的时候,iPhoneOS会检测触摸事件,并将事件放入应用程序的事件队列。然后,UIApplication对象的事件处理设施会从队列的上部逐个取出事件,将它分发到最适合对其进行处理的对象。举例来说,在一个按键上发生的触摸事件会被分发到对应的按键对象。事件也可以被分发给控制器对象和应用程序中不直接负责处理触摸事件的其它对象。

图1-2  事件和描画周期

在iPhone OS的多点触摸事件模型中,触摸数据被封装在事件对象(UIEvent)中。为了跟踪触摸动作,事件对象中包含一些触摸对象(UITouch),每个触摸对象都对应于一个正在触摸屏幕的手指。当用户把手指放在屏幕上,然后四处移动,并最终离开屏幕的时候,系统通过对应的触摸对象报告每个手指的变化。

在启动一个应用程序时,系统会为该程序创建一个进程和一个单一的线程。这个初始线程成为应用程序的主线程,UIApplication对象正是在这个线程中建立主运行循环及配置应用程序的事件处理代码。图1-3显示了事件处理代码和主运行循环的关系。系统发送的触摸事件会在队列中等待,直到被应用程序的主运行循环处理。

图1-3  在主运行循环中处理事件

请注意:运行循环负责监视指定执行线程的输入源。当输入源有数据需要处理的时候,运行循环就唤醒相应的线程,并将控制权交给输入源的处理器代码。处理器在完成任务后将控制权交回运行循环,然后,运行循环就处理下一个事件。如果没有其它事件,运行循环会使线程进入休眠状态。您可以通过Foundation框架的NSRunLoop类来安装自己的输入源,包括端口和定时器。更多有关NSRunLoop和运行循环的一般性讨论,请参见线程编程指南

UIApplication对象用一个处理触摸事件的输入源来配置主运行循环,使触摸事件可以被派发到恰当的响应者对象。响应者对象是继承自UIResponder类的对象,它实现了一或多个事件方法,以处理触摸事件不同阶段发生的事件。应用程序的响应者对象包括UIApplicationUIWindowUIView、及所有UIView子类的实例。应用程序通常将事件派发给代表应用程序主窗口的UIWindow对象,然后由窗口对象将事件传送给它的第一响应者,通常是发生触摸事件的视图对象(UIView)。

除了定义事件处理方法之外,UIResponder类还定义了响应者链的编程结构。响应者链是为实现Cocoa协作事件处理而设计的机制,它由应用程序中一组链接在一起的响应者对象组成,通常以第一响应者作为链的开始。当发生某个事件时,如果第一响应者对象不能处理,就将它传递给响应者链中的下一个对象。消息继续在链中传递—从底层的响应者对象到诸如窗口、应用程序、和应用程序委托这样的高级响应者对象—直到事件被处理。如果事件最终没有被处理,就会被丢弃。

进行事件处理的响应者对象可能发起一系列程序动作,结果导致应用程序重画全部或部分用户界面(也可能导致其它结果,比如播放一个声音)。举例来说,一个控键对象(也就是一个UIControl的子类对象)在处理事件时向另一个对象(通常是控制器对象,负责管理当前活动的视图集合)发送动作消息。在处理这个动作消息时,控制器可能以某种方式改变用户界面或者视图的位置,而这又要求某些视图对自身进行重画。如果这种情况发生,则视图和图形基础组件会接管控制权,尽可能以最有效的方式处理必要的重画事件。

更多有关事件、响应者、和如何在定制对象中处理事件的信息,请参见“事件处理”部分;更多有关窗口及视图如何与事件处理机制相结合的信息,请参见“视图交互模型”部分;有关图形组件及视图如何被更新的更多信息,则请参见“视图描画周期”部分。

基本设计模式

UIKit框架的设计结合了很多在Mac OS XCocoa应用程序中使用的设计模式。理解这些设计模式对于创建iPhone应用程序是很关键的,我们值得为此花上几分钟时间。下面部分将简要概述这些设计模式。

表1-1  iPhone应用程序使用的设计模式

设计模式

描述

模型-视图-控制器

模型-视图-控制器(MVC)模式将您的代码分割为几个独立的部分。模型部分定义应用程序的数据引擎,负责维护数据的完整性;视图部分定义应用程序的用户界面,对显示在用户界面上的数据出处则没有清楚的认识;控制器部分则充当模型和控制器的桥梁,帮助实现数据和显示的更新。

委托

委托模式可以对复杂对象进行修改而不需要子类化。与子类化不同的是,您可以照常使用复杂对象,而将对其行为进行修改的定制代码放在另一个对象中,这个对象就称为委托对象。复杂对象需要在预先定义好的时点上调用委托对象的方法,使其有机会运行定制代码。

目标-动作

控件通过目标-动作模式将用户的交互通知给您的应用程序。当用户以预先定义好的方式(比如轻点一个按键)进行交互时,控件就会将消息(动作)发送给您指定的对象(目标)。接收到动作消息后,目标对象就会以恰当的方式进行响应(比如在按动按键时更新应用程序的状态)。

委托内存模型

Objective-C使用引用计数模式来确定什么时候应该释放内存中的对象。当一个对象刚刚被创建时,它的引用计数是1。然后,其它对象可以通过该对象的retainrelease、或autorelease方法来增加或减少引用计数。当对象的引用计数变为0时,Objective-C运行环境会调用对象的清理例程,然后解除分配该对象。

有关这些设计模式更为详尽的讨论请参见Cocoa基本原理指南

应用程序运行环境

iPhoneOS的运行环境被设计为快速而安全的程序执行环境。下面的部分这个运行环境的关键部分,并就如何在这个环境中进行操作提供一些指导。

启动过程快,使用时间短

iPhoneOS设备的优势是它们的便捷性。用户通常从口袋里掏出设备,用上几秒或几分钟,就又放回口袋中了。在这个过程中,用户可能会打电话、查找联系人、改变正在播放的歌曲、或者取得一片信息。

在iPhoneOS中,每次只能有一个前台应用程序。这意味着每次用户在Home屏幕上轻点您的应用程序图标时,您的程序必须快速启动和初始化,以尽可能减少延迟。如果您的应用程序花很长时间来启动,用户可能就不喜欢了。

除了快速启动,您的应用程序还必须做好快速退出的准备。每次用户离开您的应用程序时,无论是按下Home键还是通过软件提供的功能打开了另一个应用程序,iPhoneOS会通知您的应用程序退出。在那个时候,您需要尽快将未保存的修改保存到磁盘上。如果您的应用程序退出的时间超过5秒,系统可能会立刻终止它的运行。

当用户切换到另一个应用程序时,虽然您的程序不是运行在后台,但是我们鼓励您使它看起来好像是在后台运行。当您的程序退出时,除了对未保存的数据进行保存之外,还应该保存当前的状态信息;而在启动时,则应该寻找这些状态信息,并将程序恢复到最后一次使用时的状态。这样可以使用户回到最后一次使用时的状态,使用户体验更加一致。以这种方式保存用户的当前位置还可以避免每次启动都需要经过多个屏幕才能找到需要的信息,从而节省使用的时间。

应用程序沙箱

由于安全的原因,iPhoneOS将每个应用程序(包括其偏好设置信息和数据)限制在文件系统的特定位置上。这个限制是安全特性的一部分,称为应用程序的“沙箱”。沙箱是一组细粒度的控制,用于限制应用程序对文件、偏好设置、网络资源、和硬件等的访问。在iPhoneOS中,应用程序和它的数据驻留在一个安全的地方,其它应用程序都不能进行访问。在应用程序安装之后,系统就通过计算得到一个不透明的标识,然后基于应用程序的根目录和这个标识构建一个指向应用程序家目录的路径。因此,应用程序的家目录具有如下结构:

  • /ApplicationRoot/ApplicationID/

在安装过程中,系统会创建应用程序的家目录和几个关键的子目录,配置应用程序沙箱,以及将应用程序的程序包拷贝到家目录上。将应用程序及其数据放在一个特定的地方可以简化备份-并-恢复操作,还可以简化应用程序的更新及卸载操作。有关系统为每个应用程序创建的专用目录、应用程序更新、及备份-并-恢复操作的更多信息,请参见“文件和数据管理”部分。

重要提示:沙箱可以限制攻击者对其它程序和系统造成的破坏,但是不能防止攻击的发生。换句话说,沙箱不能使您的程序避免恶意的直接攻击。举例来说,如果在您的输入处理代码中有一个可利用的缓冲区溢出,而您又没有对用户输入进行正当性检查,则攻击者可能仍然可以使您的应用程序崩溃,或者通过这种漏洞来执行攻击者的代码。

虚拟内存系统

在本质上,iPhone OS使用与Mac OS X同样的虚存系统。在iPhoneOS中,每个程序都仍然有自己的虚拟地址空间,但其可用的虚拟内存受限于现有的物理内存的数量(这和Mac OSX不同)。这是因为当内存用满的时候,iPhone OS并不将非永久内存页面(volatilepages)写入到磁盘。相反,虚拟内存系统会根据需要释放永久内存(nonvolatilememory),确保为正在运行的应用程序提供所需的空间。内存的释放是通过删除当前没有正在使用或包含只读内容(比如代码页面)的内存页面来实现的,这样的页面可以在稍后需要使用的时候重新装载到内存中。

如果内存还是不够,系统也可能向正在运行的应用程序发出通告,要求它们释放额外的内存。所有的应用程序都应该响应这种通告,并尽自己所能减轻系统的内存压力。有关如何在应用程序中处理这种通告的更多信息,请参见“观察低内存警告”部分。

自动休眠定时器

iPhoneOS试图省电的一个方法是使用自动休眠定时器。如果在一定的时间内没有检测到触摸事件,系统最初会使屏幕变暗,并最终完全关闭屏幕。大多数开发者都应该让这个定时器打开,但是,游戏和不使用触摸输入的应用程序开发者可以禁用这个定时器,使屏幕在应用程序运行时不会变暗。将共享的UIApplication对象的idleTimerDisabled属性设置为YES,就可以禁用自动休眠定时器。

由于禁用休眠定时器会导致更大的电能消耗,所以开发者应该尽一切可能避免这样做。只有地图程序、游戏、以及不依赖于触摸输入而又需要在设备屏幕上显示内容的应用程序才应该考虑禁用休眠定时器。音频应用程序不需要禁用这个定时器,因为在屏幕变暗之后,音频内容可以继续播放。如果您禁用了定时器,请务必尽快重新激活它,使系统可以更省电。有关应用程序如何省电的其它贴士,请参见“减少电力消耗”部分。

应用程序的程序包

当您连编iPhone程序时,Xcode会将它组织为程序包。程序包是文件系统中的一个目录,用于将执行代码和相关资源集合在一个地方。iPhone应用程序包中包含应用程序的执行文件和应用程序需要用到的所有资源(比如应用程序图标、其它图像、和本地化内容)。表1-2列出了一个典型的iPhone应用程序包中的内容(为了便于说明,我们称之为MyApp)。这个例子只是为了演示,表中列出的一些文件可能并不出现在您自己的应用程序包中。

表1-2  一个典型的应用程序包

文件

描述

MyApp

包含应用程序代码的执行文件,文件名是略去.app后缀的应用程序名。这个文件是必需的。

Settings.bundle

设置程序包是一个文件包,用于将应用程序的偏好设置加入到Settings程序中。这种程序包中包含一些属性列表和其它资源文件,用于配置和显示您的偏好设置。更多信息请参见“显示应用程序的偏好设置”部分。

Icon.png

这是个57 x57像素的图标,显示在设备的Home屏幕上,代表您的应用程序。这个图标不应该包含任何光亮效果。系统会自动为您加入这些效果。这个文件是必须的。更多有关这个图像文件的信息,请参见“应用程序图标和启动图像”部分。

Icon-Settings.png

这是一个29 x29像素的图标,用于在Settings程序中表示您的应用程序。如果您的应用程序包含设置程序包,则在Settings程序中,这个图标会显示在您的应用程序名的边上。如果您没有指定这个图标文件,系统会将Icon.png文件按比例缩小,然后用做代替文件。有关这个图像文件的更多信息,青参见“显示应用程序的偏好设置”部分。

MainWindow.nib

这是应用程序的主nib文件,包含应用程序启动时装载的缺省用户界面对象。典型情况下,这个nib文件包含应用程序的主窗口对象和一个应用程序委托对象实例。其它界面对象则或者从其它nib文件装载,或者在应用程序中以编程的方式创建(主nib文件的名称可以通过Info.plist文件中的NSMainNibFile键来指定,进一步的信息请参见“信息属性列表”部分)。

Default.png

这是个480 x320像素的图像,在应用程序启动的时候显示。系统使用这个文件作为临时的背景,直到应用程序完成窗口和用户界面的装载。有关这个图像文件的信息请参见“应用程序图标和启动图像”部分。

iTunesArtwork

这是个512 x 512的图标,用于通过ad-hoc方式发布的应用程序。这个图标通常由AppStore来提供,但是通过ad-hoc方式分发的应用程序并不经由AppStore,所以在程序包必须包含这个文件。iTunes用这个图标来代表您的程序(如果您的应用程序在AppStore上发布,则在这个属性上指定的文件应该和提交到App Store的文件保持一致(通常是个JPEG或PNG文件),文件名必须和左边显示的一样,而且不带文件扩展名)。

Info.plist

这个文件也叫信息属性列表,它是一个定义应用程序键值的属性列表,比如程序包ID、版本号、和显示名称。进一步的信息请参见“信息属性列表”部分。这个文件是必需的。

sun.png (或其它资源文件)

非本地化资源放在程序包目录的最上层(在这个例子中,sun.png表示一个非本地化的图像)。应用程序在使用非本地化资源时,不需要考虑用户选择的语言设置。

en.lproj

fr.lproj

es.lproj

其它具体语言的工程目录

本地化资源放在一些子目录下,子目录的名称是ISO639-1定义的语言缩写加上.lproj后缀组成的(比如en.lprojfr.lproj、和es.lproj目录分别包含英语、法语、和西班牙语的本地化资源)。更多信息请参见“国际化您的应用程序”部分。

iPhone应用程序应该是国际化的。程序支持的每一种语言都有一个对应的语言.lproj文件夹。除了为应用程序提供定制资源的本地化版本之外,您还可以本地化您的应用程序图标(Icon.png)、缺省图像(Default.png)、和Settings图标(Icon-Settings.png),只要将同名文件放到具体语言的工程目录就可以了。然而,即使您提供了本地化的版本,也还是应该在应用程序包的最上层包含这些文件的缺省版本。当某些的本地化版本不存在的时候,系统会使用缺省版本。

您可以通过NSBundle类的方法或者与CFBundleRef类型相关联的函数来获取应用程序包中本地化和非本地化图形及声音资源的路径。举例来说,如果您希望得到图像文件sun.png(显示在“响应中断”部分中)的路径并通过它创建一个图像文件,则需要下面两行Objective-C代码:

NSString* imagePath = [[NSBundle mainBundle] pathForResource:@"sun" ofType:@"png"];
UIImage* sunImage = [[UIImage alloc] initWithContentsOfFile:imagePath];

代码中的mainBundle类方法用于返回一个代表应用程序包的对象。有关资源装载的信息请参见资源编程指南

信息属性列表

信息属性列表是一个名为Info.plist的文件,通过Xcode创建的每个iPhone应用程序都包含一个这样的文件。属性列表中的键值对用于指定重要的应用程序运行时配置信息。信息属性列表的元素被组织在一个层次结构中,每个结点都是一个实体,比如数组、字典、字符串、或者其它数值类型。

在Xcode中,您可以通过在Project菜单中选择Edit ActiveTarget TargetName命令、然后在目标的Info窗口中点击Properties控件来访问信息属性列表。Xcode会显示如图1-4所示的信息面板。

图1-4  目标Info窗口的属性面板

属性面板显示的是程序包的一些属性,但并不是所有属性都显示在上面。当您选择“OpenInfo.plist as File” 按键或在Xcode工程中选择Info.plist文件时,Xcode会显示如图1-5所示的属性列表编辑器窗口,您可以通过这个窗口来编辑属性值和添加键-值对。您还可以查看添加到Info.plist文件中的实际键名,具体操作是按住Control键的同时点击编辑器中的信息属性列表项目,然后选择上下文菜单中的ShowRaw Keys/Values命令。

图1-5  信息属性列表编辑器

Xcode会自动设置某些属性的值,其它属性则需要显式设置。表1-3列出了一些重要的键,供您在自己的Info.plist文件中使用(在缺省情况下,Xcode不会直接显示实际的键名,因此,下表在括号中列出了这些键在Xcode中显示的字符串。您可以查看所有键的实际键名,具体做法是按住Control键的同时点击编辑器中的信息属性列表项目,然后选择上下文菜单中的ShowRawKeys/Values命令)。有关属性列表文件可以包含的完整属性列表及系统如何使用这些属性的信息,请参见运行环境配置指南

表1-3  Info.plist文件中重要的键

CFBundleDisplayName (程序包显示名)

显示在应用程序图标下方的名称。这个值应该本地化为所有支持的语言。

CFBundleIdentifier (程序包标识)

这是由您提供的标识字符串,用于在系统中标识您的应用程序。这个字符串必须是一个统一的类型标识符(UTI),仅包含字母数字(A-Za-z0-9),连字符(-),和句号(.);且应该使用反向DNS格式。举例来说,如果您的公司的域名为Ajax.com,且您创建的应用程序名为Hello,则可以将字符串com.Ajax.Hello作为应用程序包的标识。

程序包的标识用于验证应用程序的签名。

CFBundleURLTypes (URL类型)

这是应用程序能够处理的URL类型数组。每个URL类型都是一个字典,定义一种应用程序能够处理的模式(如httpmailto)。应用程序可以通过这个属性来注册定制的URL模式。

CFBundleVersion (程序包版本号)

这是一个字符串,指定程序包的连编版本号。它的值是单调递增的,由一或多个句号分隔的整数组成。这个值不能被本地化。

LSRequiresIPhoneOS

这是一个Boolean值,用于指示程序包是否只能运行在iPhone OS系统上。Xcode自动加入这个键,并将它的值设置为true。您不应该改变这个键的值。

NSMainNibFile (主nib文件的名称)

这是一个字符串,指定应用程序主nib文件的名称。如果您希望使用其它的nib文件(而不是Xcode为工程创建的缺省文件)作为主nib文件,可以将该nib文件名关联到这个键上。nib文件名不应该包含.nib扩展名。

UIStatusBarStyle

这是个字符串,标识程序启动时状态条的风格。这个键的值基于UIApplication.h头文件中声明的UIStatusBarStyle常量。缺省风格是UIStatusBarStyleDefault。在启动完成后,应用程序可以改变状态条的初始风格。

UIStatusBarHidden

这个一个Boolean值,指定在应用程序启动的最初阶段是否隐藏状态条。将这个键值设置为true将隐藏状态条。缺省值为false

UIInterfaceOrientation

这是个字符串,标识应用程序用户界面的初始方向。这个键的值基于UIApplication.h头文件中声明的UIInterfaceOrientation 常量。缺省风格是UIInterfaceOrientationPortrait

有关将应用程序启动为景观模式的更多信息,请参见“以景观模式启动”部分。

UIPrerenderedIcon

这个一个Boolean值,指示应用程序图标是否已经包含发光和斜面效果。这个属性缺省值为false。如果您不希望系统在您的原图上加入这些效果,则将它设置为true。

UIRequiredDeviceCapabilities

这是个信息键,作用是使iTunes和App Store知道应用程序运行需要依赖于哪些与设备相关的特性。iTunes和移动AppStore程序使用这个列表来避免将应用程序安装到不支持所需特性的设备上。

这个键的值可以是一个数组或者字典如果您使用的是数组,则数组中存在某个键就表示该键对应的特性是必需的;如果您使用的是字典,则必须为每个键指定一个Boolean值,表示该键是否需要。无论哪种情况,不包含某个键表示该键对应的特性不是必需的。

如果您需要可包含在这个字典中的键列表,请参见表1-4。这个键在iPhoneOS 3.0及更高版本上才被支持。

UIRequiresPersistentWiFi

这是个Boolean值,用于通知系统应用程序是否使用Wi-Fi网络进行通讯。如果您的应用程序需要在一段时间内使用Wi-Fi,则应该将这个键值设置为true;否则,为了省电,设备会在30分钟内关闭Wi-Fi连接。设置这个标志还可以让系统在Wi-Fi网络可用但未被使用的时候显示网络选择对话框。这个键的缺省值是false

请注意,当设备处于闲置状态(也就是屏幕被锁定的状态)时,这个属性的值为true是没有作用的。这种情况下,应用程序会被认为是不活动的,虽然它可能在某些级别上还可以工作,但是没有Wi-Fi连接。

UISupportedExternalAccessoryProtocols

这是个字符串数组,标识应用程序支持的配件协议。配件协议是应用程序和连接在iPhone或iPodtouch上的第三方硬件进行通讯的协议。系统使用这个键列出的协议来识别当配件连接到设备上时可以打开的应用程序。

有关配件和协议的更多信息,请参见“和配件通讯”部分。这个键只在iPhoneOS 3.0和更高版本上支持。

UIViewGroupOpacity

这是个Boolean值,用于指示CoreAnimation子层是否继承其超层的不透明特性。这个特性使开发者可以在仿真器上进行更为复杂的渲染,但是对性能会有显著的影响。如果属性列表上没有这个键,则其缺省值为NO

这个键只在iPhone OS 3.0和更高版本上支持。

UIViewEdgeAntialiasing

这是个Boolean值,用于指示在描画不和像素边界对齐的层时,CoreAnimation层是否进行抗锯齿处理。这个特性使开发者可以在仿真器上进行更为复杂的渲染,但是对性能会有显著的影响。如果属性列表上没有这个键,则其缺省值为NO

这个键只在iPhone OS 3.0和更高版本上支持。

如果信息属性文件中的属性值是显示在用户界面上的字符串,则应该进行本地化,特别是当Info.plist中的字符串值是与本地化语言子目录下InfoPlist.strings文件中的字符串相关联的键时。更多信息请参见“国际化您的应用程序”部分。

表1-4列出了和UIRequiredDeviceCapabilities键相关联的数组或字典中可以包含的键。您应该仅包含应用程序确实需要的键。如果应用程序可以通过不执行某些代码路径来适应设备特性不存在的情况,则不需要使用对应的键。

表1-4  UIRequiredDeviceCapabilities键的字典键

描述

telephony

如果您的应用程序需要Phone程序,则包含这个键。如果您的应用程序需要打开tel模式的URL,则可能需要这个特性。

sms

如果您的应用程序需要Messages程序,则包含这个键。如果您的应用程序需要打开sms模式的URL,则可能需要这个特性。

still-camera

如果您的应用程序使用UIImagePickerController接口来捕捉设备照相机的图像时,需要包含这个键。

auto-focus-camera

如果您的应用程序需要设备照相机的自动对焦能力,则需要包含这个键。虽然大多数开发者应该不需要,但是如果您的应用程序支持微距摄影,或者需要更高锐度的图像以进行某种处理,则可能需要包含这个键。

video-camera

如果您的应用程序使用UIImagePickerController接口来捕捉设备摄像机的视频时,需要包含这个键。

wifi

当您的应用程序需要设备的网络特性时,包含这个键。

accelerometer

如果您的应用程序使用UIAccelerometer接口来接收加速计事件,则需要包含这个键。如果您的程序仅需要检测设备的方向变化,则不需要。

location-services

如果您的应用程序使用CoreLocation框架来访问设备的当前位置,则需要包含这个键(这个键指的是一般的位置服务特性。如果您需要GPS级别的精度,则还应该包含gps键)。

gps

如果您的应用程序需要GPS(或者AGPS)硬件,以获得更高精度的位置信息,则包含这个键。如果您包含了这个键,就应该同时包含location-services键。如果您的程序需要更高精度的位置数据,而不是由蜂窝网络或Wi-fi信号提供的数据,则应该要求只接收GPS数据。

magnetometer

如果您的应用程序使用Core Location框架接收与方向有关的事件时,则需要包含这个键。

microphone

如果您的应用程序需要使用内置的麦克风或支持提供麦克风的外设,则包含这个键。

opengles-1

如果您的应用程序需要使用OpenGL ES 1.1 接口,则包含这个键。

opengles-2

如果您的应用程序需要使用OpenGL ES 2.0 接口,则包含这个键。

iPhone OS编程指南(一)相关推荐

  1. iPhone应用程序编程指南

    介绍 请注意:本文档之前命名为iPhone OS编程指南. iPhone SDK为创建iPhone的本地应用程序提供必需的工具和资源.在用户的Home屏幕上,iPhone的本地应用程序表示为图标.它们 ...

  2. (转)---iPhone应用程序编程指南

    请注意:本文档之前命名为iPhone OS编程指南. iPhone SDK为创建iPhone的本地应用程序提供必需的工具和资源.在用户的Home屏幕上,iPhone的本地应用程序表示为图标.它们和运行 ...

  3. iPhone应用程序编程指南(窗口和视图)

    窗口和视图 窗口为内容显示提供背景平台,而视图负责绝大部分的内容描画,并负责响应用户的交互. 什么是窗口和视图? UIWindow的作用 iPhone应用程序通常只有一个窗口,表示为一个UIWindo ...

  4. iPhone应用程序编程指南(文本和Web)

    关于文本和Web的支持 文本视图 UIKit框架提供三个显示文本内容的基本类: UILabel 显示静态文本字符串 UITextField 显示单行可编辑文本 UITextView 显示多行可编辑文本 ...

  5. iPhone应用程序编程指南(图形和描画)

    iPhone OS为创建高质量的图形提供两种路径:即通过OpenGL进行渲染,或者通过Quartz.Core Animation.和UIKit进行渲染. UIKit的图形系统 在iPhone OS上, ...

  6. iPhone编程指南学习笔记

    为什么80%的码农都做不了架构师?>>>    UIWindow 在创建应用程序窗口时,您应该总是将其初始的边框尺寸设置为整个屏幕的大小.如果您的窗口是从nib文件装载得到,Inte ...

  7. Mac OS X地址簿编程指南

    Address Book Programming Guide for Mac OS X 一.简介 地址簿是一种围绕联系人和组信息中心数据.可以查看这些信息应用程序.以及在程序中访问这些信息的编程接口的 ...

  8. 2011年3月华章新书书讯:ASP.NET本质论、Erlang编程指南、SNS网站构建

    ASP.NET本质论 深入剖析ASP.NET的运行机制和工作原理,带你领略ASP.NET的本质和精髓 包含大量开发技巧和最佳实践,为开发稳定而高效的ASP.NET应用提供绝佳指导 SNS网站构建 提供 ...

  9. CoreAnimation编程指南(简介)

    一.核心动画编程介绍    1.本文档介绍了在使用核心动画时所涉及的基本概念.核心动画的是Objective – C的框架,它通过简单的动画编程接口来提供一套高性能的动画引擎.    2.你应该阅读此 ...

最新文章

  1. 一个很好的性能监测工具dstat
  2. python nonetype_【已解决】Python程序错误:TypeError: ‘NoneType’ object is not iterable
  3. 【读书笔记】2015年考研英语二真题翻译(帮你克服艰难之路的真理+熟路效应)
  4. 2017双11技术揭秘—阿里数据库计算存储分离与离在线混布
  5. linux多媒体功能,Ubuntu 8.04中文强化版 多媒体功能更强大
  6. 空间数据引擎oracle_Oracle-Spatial空间数据库基础
  7. 海康RTSP客户端连接深入分析
  8. 【网络】HTTP 协议中 URI 和 URL 有什么区别?
  9. MySQL存储过程、函数、视图、触发器、索引和锁的基本知识
  10. 简约黑板擦特效表白网源码 附带wap自适应
  11. 考拉情书---一片道歉叶
  12. js相册图片抖动放大展示效果
  13. 华为新版Datacom认证介绍
  14. 计算机微程序控制器实验报告,计算机组成原理微程序控制器实验报告
  15. OPENCART之兼容多种浏览器的加入收藏夹扩展功能插件(CROSS-BROWSER BOOKMAR
  16. rpc介绍,和PHP常用的rpc框架
  17. USB 中MTP和UMS 模式
  18. 7.最大最小距离算法与最大最小距离
  19. 伽利略或洛伦兹变换不适用于波动
  20. 全国计算机考试vb考试知识点汇总,2020年计算机等级VB考试易考点归纳

热门文章

  1. stm32f769 寄存器配置SD卡---移植fatfs
  2. Excel VBA高级编程 - 根据关键字自动搜索,自动生成下拉菜单
  3. 测试岗外包4年终上岸,这段日子说起来都是泪啊
  4. JAVA网络传输乱码问题
  5. 【人工智能】基于百度AI+Python编程的简单应用:关于人像照片动漫化的分析实现(可进行批量化处理)——教你看到二次元中的自己
  6. 服务端渲染可以用ajax吗,服务端渲染(SSR)
  7. js获取一年前的时间,几个月前的今天
  8. 技术人员通往财务自由之路
  9. ES中同时使用should和must导致只有must生效解决方案
  10. OSChina 周六乱弹 —— 我一直把一哥们当朋友,但