ndscapeRight)演示。通过设置CFBundleURLTypes可以注册自定义应用程序URL方案(如myCustomApp://)。
1.3.4 图标和默认图像
Icon.png和Default.png是两个重要的图像文件。Icon.png是应用程序图标。Default.png(官方称为“启动图像”)提供在应用程序启动时显示的初始屏幕。与Default.png
不同,图标的文件名可以随意指定。
苹果公司建议将Default.png与应用程序背景保持一致。许多开发人员使用Default.png启动图像作为初始图标或作为“请稍候”消息。这与苹果公司的人性化界面指导方针(
启动图像应显示连贯的画面,而不是显示广告或为延迟表示歉意)相违背,但却是完全可以理解的应用。
“官方”应用程序图标大小为57*57px。SpringBoard会自动调整较大的图像,并自动平滑图像的角,自动添加光亮效果。如果需要使用预渲染的图像,就在Info.plist文件中
将UIPrerenderedIcon设置为<true />。
1.3.5 XIB文件
说明:开发不使用XIB或NIBInterface-Builder束的程序时,需要从Info.plist中删除NSMainNibFile键,并放弃项目自动生成的MainWindow.xib文件。
1.3.6 应用程序束中不存在的文件
包括首选项文件(通常存储在Library/Preferences下的应用程序沙盒中)、应用程序插件(目前存储在/System/Library中,且对于一般开发不可用)和文档(存储在
Documents下的沙盒中)。
另一项缺少的内容是ApplicationSupport文件夹。要将支持数据复制到Documents或Library文件夹中。
1.3.7 沙盒
应用程序对文件系统的访问只限于一组最基本的文件夹、网络资源和硬件。还要遵循下面的原则:
1)不能访问其他沙盒。
2)不能共享玩具。不能共享数据。不得弄乱办公室。文件必须位于沙盒提供的文件夹中,并且不能将文件复制到其他应用程序文件夹中,也不能从其他应用程序文件夹复制
文件
3)应用程序拥有自己的Library、Documents和/tmp文件夹。
除了这些,应用程序必须具有数字签名,通过编码的应用程序标识符向操作系统证明自己的身份,该标识符必须在苹果公司的开发人员计划网站创建。从有利的一面来说,无
论何时将设备插入到其主计算机中,沙盒都能让所有应用程序数据保持同步。从不利的一面来说,苹果公司此时并未明确如何从Windows或Macintosh桌面应用程序访问这些同
步数据。
说明:沙盒规范文件(使用扩展名.sb)存储在/var/mobile/Applications中,其中还包括一些实际的沙盒文件夹。这些文件用于控制权限,如对文件系统中各数据位的读写
访问权。如果出现这种可能性,则不要直接编辑此文件,否则应用程序有可能受损而无法使用。示例沙盒文件通常位于/usr/share/sandbox文件夹中。
1.4. 平台限制
1.4.1 存储限制
1.4.2 数据访问限制:可以访问因特网上的数据
1.4.3 内存限制:内存管理非常重要。
说明:Xcode使用SDK随带的pngcrush实用工具自动优化PNG图像。(该程序位于iPhoneOS平台文件夹/Developer中。在命令行中带-iphone选项运行该工具,将标准PNG文件转
换为iPhone支持的格式。)尽可能使用PNG图像。
1.4.4 交互限制
1.4.5 电量限制
1.4.6应用程序限制:第三方开发人员不能开发在后台运行的应用程序,如苹果公司的Mail和Phone实用工具。程序每次运行时,他必须情况一切是非,然后才将控制传递给
用户选择的下一个应用程序。不能让检查新消息或定期发送更新的后台程序一直运行下去。一些爱好者创建的“OpenSDK”忽略了此限制,但是使用这些工具创建的应用程序
无法添加到iPhone App Store中,因而也不能在其上销售。
另一方面,苹果公司不支持推送(push)来自web服务的数据。已注册的服务可以将标记编号和消息推送给用户,让他们知道数据正在这些服务器上等待。
说明:根据iPhone的服务条款,不能为iPhone应用程序创建外部框架,也不能在提交给AppStore的应用程序中使用Cocoa的插件结构。
1.4.7 用户行为限制
1.5 SDK限制
1)垃圾收集仍不可用,并且可能始终如此。
2)许多库只得到了部分实现。
3)公共SDK框架并不像私有框架那么多样化
1.6 编程泛型
面向对象泛型和模型-视图-控制器(MVC)设计模式。为此,引入了委托(控制器)、数据源方法(模型)和自定义的视图类(视图)。
1.6.1 面向对象编程
1.6.2 模型-视图-控制器
1,视图类
UIView和UIViewController。他们负责定义和放置所有屏幕元素。
几乎所有用户界面类都继承自UIView或其父类UIResponder。重要的UIView类包括:UITextViews、UIImageViews和UIAlertViews等。UIWindow类(一种UIView)提供到应用程
序的视口(viewport),是显示的根本要素。
视图是分层结构,由子视图树组成。要显示某个视图,可以将它设置为主窗口的内容视图,也可以将它添加到另一个视图中。通过addSubview添加。
严格地说,UIViewController类并不是MVC概念中的控制器。
还有UINavigationController和UITabBarController这两个特殊的控制器可以神奇地处理视图切换。
每个UIViewController子类都实现了自己的loadView方法。该方法对控制器的子视图进行布局,并建立所有的触发、回调和委托。
2,控制器:委托、目标操作和通知
通知支持应用程序中的对象相互交流,以及与系统上的其他应用程序通信。通过广播信息,通知支持对象发送状态消息:“我已更改”、“我已经开始某任务”。
其他对象可能在监听这些广播,也可能没有。为了“听到”通知,对象必须向通知中心注册并开始监听消息。iPhone至少实现了4种通知中心。
1)NSNotificationCenter。这是应用程序内部通知的黄金标准。通过这种通知中心,可以订阅任何一个或所有通知,并监听对象之间的通信。通知得到了完全实现,并可以
携带数据和通知名称。这种“名称+数据”的实现方式提供了极大的灵活性,可以使用此中心执行复杂的消息传递。
2)NSDistributeNotificationCenter:他在iPhone并未得到完全实现,应避免使用他。
3)DarwinNotificationCenter:iPhone依赖Darwin通知中心实现应用程序间消息传递。他受到了限制,只支持广播通知,并且不允许通过这些通知发送数据。因此,可以宣
布一些项目已被更改,但不能发送关于被修改项目的信息。尽管如此,Darwin通知仍然可以信赖且非常健壮。消息可以可靠地送达。Darwin通知是使用标准BSD通知构建的(
例如notify_post()、notify_register_mach_port()等)。
4)TelephonyNotificationCenter:电话通知是私有且未发布的。遗憾的是,苹果公司并未开放此中心,但如果你悄悄监听这个具有特殊用途的中心,则可以知道电话呼叫和
SMS信息何时到达。
订阅通知中心非常简单。将应用程序委托添加为已注册的观察者。提供一个任意的选择器,以在通知到达时调用。该方法接受一个参数,及NSNotification。将名称和对象参
数设置为nil,确保回调方法将听到所有应用程序通知。
所有通知都包含3个数据元素:通知名称、相关对象和用户信息字典。如果不确定应用程序的UIKit对象生成了哪些通知,则指定回调打印出接收到的所有通知的名称--例如,
NSLog(@"%@",[notificationname])。苹果公司针对通知协议提供的文档说明并没有委托和数据源协议文档那么丰富细致。
通知的种类因当前正在执行的任务而异。例如,旋转应用程序时的通知包括UIApplicationWillChangeStatusBarOrientationNotification和
UIDeviceOrientationDidChangeNotification。在某些情况下,这些通知与已有的委托方法严格对应,但在有些情况下,却并非如此,这时需要监听通知,并编写程序查找苹
果公司委托协议实现中的缺口。监听方式如下:
[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(trackNotifications:) name:nil object:nil];
3,模型
1)数据源:指任何向另一个对象提供所需数据的对象。
2)UIApplication对象:从理论上说,你会假设iPhone“模型”组件以UIApplication类为中心。在苹果公司SDK中,每个应用程序都刚好包含一个UIApplication实例,你可
以通过[UIApplicationsharedInstance]来引用他。
大多数情况下,除非你需要在Safari中打开URL,恢复重要窗口或调整状态栏的外观,否则完全可以忽略UIApplication。我们围绕自定义应用程序委托类来构建程序,这个类
负责在应用程序启动时进行设置,以及在应用程序终止时关闭进程。否则,将其余模型职责交给自定义UIViewController类中的方法,或交给自定义模型类。
说明:使用 [[UIApplicationsharedInstance] keyWindow] 查找应用程序的主窗口对象
3)公开数据源和委托方法:
除了监听通知之外,消息跟踪还是一个宝贵的工具。respondsToSelector
1.7 构建iPhone应用程序主干
1)main()函数 (始终使用):对于iPhone而言,此函数主要用于内存管理以及启动应用程序事件循环
2)applicationDidFinishLaunching:方法(始终使用):是程序中触发的第一个方法。在其中创建基本窗口、设定内容并指定他作为应用程序的关键响应者
3)ApplicationWillTerminate:方法(经常使用):支持在将控制交回SpringBoard之前,处理任何状态最终化。此方法用来保存默认值、更新数据以及关闭文件。
4)loadView方法(始终使用):假定你已经围绕UIViewController构建了自己的应用程序,强制的loadView方法将设置屏幕并布局任何子视图。要确保从
UITableViewController或UITabBarController等专门的子类继承时调用[superloadView]
5)shouldAutorotateToInterfaceOrientation:方法(经常使用)。
1.8 Hello World应用程序
#import <UIKit/UIKit.h>
@class UIImageView;
@interface HelloController:UIViewController
{ UIImageView *contentView;
}
@end
@implementation HellController
- (id)init
{
if (self=[super init])
{
self.title=[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleName"];
}
return self;
}
- (void)loadView
{
contentView=[[UIImageView alloc]initWithFrame:[[UIScreen mainScreen] applicationFrame]];
[contentView setImage:[UIImageimageNamed:@"helloworld.png"]];
self.view=contentView;
[contentView release];
contentView.autoresizesSubviews=YES;
contentView.autoresizeingMask=(UIViewAutoresizingFlexibleWidth| UIViewAutoresizingFlexibleHeight);
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)dealloc
{
[contentView release];
[super dealloc];
}
@end
@interface SampleAppDelegate:NSObject<UIApplicationDelegate> {
}
@end
@implementation SampleAppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application{
UIWindow *window=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController*nav=[[UINavigationController alloc]initWithRootViewController:[[HelloController alloc] init]];
[window addSubView:nav.view];
[window makeKeyAndVisible];
}
- (void)applicationWillTerminate:(UIApplication *)application{
//Handle and final state matters here
}
- (void)dealloc {
[super dealloc];
}
@end
int main(int argc,char *argv[])
{
NSAutorelease *pool=[[NSAutorelease alloc]init];
intretVal=UIApplicationMain(argc,argv,nil,@"SampleAppDelegate");
[pool release];
return retVal;
}
1.8.1 类
1.8.2 代码
此程序包含两个类定义(HelloController类和SampleAppDelegate类)以及main()函数。此处使用单个文件的形式是为了确保可读性。但在实际应用程序中要使用标准的多文
件系统。
main()函数由Xcode自动生成,基本未经过开发人员手动更改。他调用UIApplicationMain(),向她传递主应用程序委托的名称,在本例中为SampleAppDelegate。
随后调用的是applicationDidFinishLaunching[colon]方法。此处,代码使用标准mainScreen几何函数创建了一个新窗口。它构建了一个导航控制器,并分配了一个新的
HelloController(UIViewController子类)作为其根视图控制器。他指定HelloController视图作为导航控制器的主要子视图。此操作可以让程序支持完整的导航栏特性。
要完成设置窗口,此程序设置nav.view(该导航栏的整个视图)作为窗口的子视图,并调出该窗口。
在HelloController类中,loadView将创建主应用程序视图(在本例中为加载helloworld.png内容的UIImageView)。使用self.ivew=contentView将图像视图分配给控制器。
1.8.3 关于示例代码和内存管理的注意事项
在本书的代码中,我没有过多地考虑内存管理,只为使示例能稳定运转。你在阅读代码时可能会发现一些似乎无关的驻留内容和各版本缺乏匹配,都是出于这个原因。可以根
据需要为代码添加适当的内存管理限制。
1.9 构建Hello World应用程序
1.9.1 创建iPhone项目
1.9.2 运行主干
默认情况下,项目的编译和启动将始终在仿真器中完成。可以选择Project,Set ActiveSDK,指定Xcode是为基于Leopard的仿真器还是为iPhone构建应用程序。在撰写本书时,未经认证的开发人员不能将软件加载到iPhone中。iPhone开发人员计划的基本费用是99美元/年,可以访问on-iPhoneApp Store。要加入该计划,请访问
http://developer.apple.com/iphone/program
1.9.3 定制iPhone项目
以下步骤可将标准主干转换为Hello World项目。
1)删除类:选中Groups&Files中的Classes文件夹,然后按Delete。单击AlsoMove to Trash
2)删除.xib文件:在本项目中,不需要使用他。
3)从Info.plist文件中删除两行:他们分别是带NSMainNibFile键的行及MainWindow字符串后面的一行。
4)添加一个Images文件夹。右键Groups&Files列中的Helloworld并选择Add,NewGroup。将新文件夹命名为Pictures。
5)在项目中添加图像:将图像添加到Pictures文件夹
6)替换main.m:打开main.m并将其内容更改为前面的内容。
7)选择iPhone仿真器。选择Project,Set Active SDK,iPhone Simulator。
8)运行程序:选择Build,Build & Run(Cmd+R)。
初次运行模拟iPhone应用程序时可能需要了解以下操作:
1)选择屏幕:Cmd+Left和Cmd+Right旋转仿真器
2)返回主屏幕:
3)锁定“电话”:选择Hardware,Lock(cmd+L)
4)查看控制台:在Xcode中,选择Run,Console(Cmd+Shift+R)查看Xcode控制台窗口。printf、NSLog和CFShow消息默认都在此窗口中发送。在NSLog消息未出现的情况下,使用Xcode组织程序(Window,Organizer,Console)或打开/Applications/Utilities/Console查看NSLog消息。
5)运行检测:使用Run,Start with PerformanceTool选择仿真器要使用的检测(Instruments)模版(如Object Allocations或CPUSampler)。检测在应用程序运行期间监视内存和CPU使用。
说明:虽然Organizer窗口可直接访问故障日志,但你可能希望同时启用Developer Mode for CrashReporter。这就允许及时查看跟踪反馈,而不需要总是单击Report。为此,打开/Developer/Applications/Utilities/CrashReporterPrefs,选择Developer,然后退出。
1.9.4 编辑标识信息
默认Info.plist文件支持创建工作程序,但默认状态无法正确处理iPhone设置(provisioning),后者是电话应用程序测试和分发的必要前提条件,本章将在稍后讨论此内容。iPhones要求一个有符号的标识,可以在苹果公司的iPhone开发人员程序网站(http://developer.apple.com/iphone/program)生成该标识。对于仅限于仿真器的应用,可以双击Info.plist文件在新窗口中打开它。此处,你将看到程序的应用程序标识符,只可以编辑公司名称条目。
Info.plist文件并不是定制工作的最后一项。关闭Info并双击InfoPlist.strings。此文件与许多其他项目文件列在一处。编辑"@__MyCompanyName__,2008"为程序使用实际的版权声明。再次选择File,Save(Cmd+S)保存更改。
1.9.5 使用调试器
1,设置断点
2,运行程序:确保断点为深蓝色,且Xcode屏幕顶部的按钮显示为“Deactivate”(这表示断点处于活动状态),然后运行程序。程序在运行到断点处时会自动停止,蓝色箭头上方将出现一个红点。
3,打开Debugger窗口
选择Run,Debugger(Cmd+Shift+Y)打开主调试器,并选择Run,Console(Cmd+Shift+R)打开控制台窗口。调试器提供一个用于检查程序对象的图形前端。控制台提供一个标准GnuDebugger(gdb)命令行。
4,检查:在断点处停止之后,可以使用交互式调试器或dgb命令行检查程序中的对象。对于本例,依次查看Arguments、self、contentView、UIView和_viewFlags,确认已正确设置了autoresizeMask。假设苹果公司未更改其常量,此掩码应为18,对应的灵活宽度和高度分别为2和16.
5,考虑其他断点选项:
Xcode窗口顶部的断点菜单支持添加自定义断点操作来代替在执行中使用的一般断点。
1.10 苹果公司的iPhone开发人员计划
1.10.1 开发电话
首次使用标准USB线将iPhone连接到计算机时,Xcode会检查你的单元。如果希望使用你的设备进行开发,需确认该设备;否则单击Ignore。开发单元只能专用于开发。使用设备做为开发单元意味着他受机载数据更改的影响,并且可能不再是可靠的单元。
1.10.2 应用程序标识符
苹果公司使用两类设置:开发设置和分发设置。通过开发设置,可以将软件下载到iPhone中进行测试。分发设置可以创建适合AppStore或临时分发的应用程序。iPhone将其活动设置列在Settings,General,Profile中。
要分发iPhone上的应用程序,苹果公司要求你在他们的站点注册ApplicationID。为此,你必须是注册过的团队管理员。使用苹果公司iPhone Dev Center上的DeveloperProgram门户。使用Program Portal,AppIDs输入新ID,然后通过Program,Provisioning创建一个设置配置文件。
要开发应用程序,可以使用特定的应用程序标识符在手机上进行测试。更好的方式是创建一个反向域的通配符com.mydomain.*应用程序标识符完成所有设置,以进行测试。此通配符设置必须匹配Info.plist文件中的各应用程序ID。我使用的是com.sadun.*。选取一个反向域来描述你的单位或个人身份。
在程序门户中创建通配符设置之后,下载新开发设置配置文件。返回Xcode,执行以下操作。
1)将mobileprovision文件拖到组织程序中。或者将它拖到Xcode应用程序图标上。
2)从项目窗口中选择Debug或Release。
3)在项目窗口的Groups*Files列表中,打开Targets并双击应用程序名称。这将打开一个TargetInfo对话框。
4)在Target Info窗口中选择Debug或Release,匹配在项目窗口中选择的内容。
5)单击Properties选项卡。在Identifier字段中输入新应用程序ID。如果设置了通配符,则输入实际的应用程序名称,而不是通配符(例如,应该是com.mydomain.myapplication,而不是com.mydomain.*)。
6)单击Build选项卡。将Code Signing Identify设置为Any iPhone OS Device和iPhoneDeveloper。此阶段用于匹配密钥链中的开发证书。要检查密钥链,打开/Applications/Utilities/KeychainAccess。My Certificates类别应该包含至少一个证书,该证书的名称中应有iPhoneDeveloper。如果你已经针对分发进行了签名,则还可能有一个iPhone分发证书。
7)将Code Signing Provision Profile设置为Any iPhone OSDevice,然后在弹出菜单中指定刚才为应用程序ID创建的设置的名称。(不要为Code SigningIdentity选择Default ProvisioningProfile。应用程序既不会加载,也不会在iPhone上运行。)
完成这些步骤之后,你应该能够针对iPhone编译应用程序(Project,Set Active SDK,Device-iPhoneOS),安装它并在设备中运行它。如果遇到任何问题,请参阅苹果公司的文档或咨询开发人员技术支持。
1.11 从Xcode到iPhone:Organizer界面
将项目添加到Xcode中之后,可以使用Xcode的Organizer工具(Window,Organizer或Control-Command-O)来管理开发。此窗口形成了开发计算机与被测试的iPhone或iPod之间的访问控制中心。可以通过此窗口添加和删除应用程序,查看测试时的控制台结果,检查故障日志,以及在测试代码时截取测试单元的屏幕快照。Organizer控制台提供的主要特性如下所示:
此处,可以加载固件,安装和删除应用程序,读取故障日志以及截取基于设备的屏幕快照等。
1.11.1 PROJECTS & SOURCES 列表
将当前项目拖到Organizer控制台中,这样可以便于管理它们。添加之后,双击项目名称打开相应项目。可以添加各个源文件以及完整的项目。使用Organizer窗口顶部的Build、Clean、Run和Action选项可以直接在Organizer中执行更多开发任务。
1.11.2 DEVICES 列表
DEVICES列表显示已授权作为开发平台的设备的名称和状态。各名称右侧的指示符显示是否已添加了设备(绿灯表示是,红灯表示否)。
1.11.3 Summary 选项卡
Summary选项卡显示iPhone或iPodtouch的名称、容量、序列号和标识符。在该选项卡中,可以设置单元(即准许他运行在Xcode中构建的项目),添加和删除应用程序,以及记载最新的固件。
每个开发人员许可证都允许在测试时最多设置5个iPhones/iPodtouch。Provisioning列表显示你的单元可用的应用程序设置列表。你需要选中希望使用的设置。设置将正确哪些应用程序可以而哪些应用程序不可以在设备上运行。根据规则,分发设置将列于此处(还有开发设置,但他们显示为灰色)。
Summary选项卡底部显示已安装的应用程序列表。可以使用+而-按钮添加或删除应用程序。打开各应用程序名称旁边的三角形以显示与该应用程序相关的数据(Documents和Library文件夹)。
1.11.4 Console选项卡
1.11.5 Crash Logs 选项卡
1.11.6 Scrrenshot 选项卡
1.11.7 线缆连接:必须通过USB线连接:
1)拔下线缆时,所有交互式调试、控制台和屏幕快照特性都将关闭。因此,需要始终插入该线缆。
2)插上线缆的iPhone使用不太方便。
3)线缆接口位于单元的底部而不是顶部,这意味着非常容易碰到线缆,将iPhone摔倒地板上。
1.11.8 在iPhone上测试应用程序
在iPhone上测试应用程序之前,需要首先针对iPhone的ARM处理器编译源代码,并将该束复制到自己的单元中。所幸,Xcode允许方便地选择是针对仿真器编译iPhone应用程序,还是针对连接设备编译iPhone应用程序。步骤如下:
1)将经过设置的iPhone连接到Macintosh。
2)选择Project,Set ActiveSDK,Device,并像在仿真器中的操作那样编译应用程序。确保已经设置好应用程序(Target,Build,Code SigningIdentify和Target,Build,Code Signing ProvisioningProfile),并将匹配的项目标识符添加到Target,Properties,Identifier。
3)编译项目并通过Run,Go或Run,Run运行它。这些菜单选项将编译程序,并为iPhone准备好应用程序。然后,他们将安装并运行程序。
4)等待。编译、签名、沙盒以及在iPhone上安装应用程序需要花费一些时间,特别是当项目文件较大且iPhone上已经有了若干个应用程序时。在加载程序时可以休息片刻。
安装好应用程序之后,他将自动启动,如果已经使用调试器进行了编译(Project,Set Active BuildConfiguration,Debug),则GnuDebugger(gdb)将在Xcode调试控制台窗口中打开。调试功能在退出应用程序之前仍然可用。可以通过Xcode(通常通过编译新版本的程序并准备安装它)或按下iPhone上的Home键退出应用程序。
在iPhone上进行测试很重要。在仿真器上测试简单而方便,但它远远算不上是完整的iPhone测试体验。
说明:SpringBoard通过两种系统通知了解新的和已删除的应用程序:com.apple.mobile.application_installed和com.apple.mobile.application_uninstalled。Xcode将这些通知发送给Darwin通知中心,然后SpringBoard开始监听。
1.11.9 编译以分发
向App Store提交应用程序需要针对分发(不是开发)编译程序。简要步骤如下。
1)在iPhone程序门户网站创建一个分发证书。将其下载到Macintosh,然后添加到密钥链。只需执行一次此操作。创建开发或分发认证之后,无论构建了多少个应用程序,他都将保留在密钥链中。
2)如果尚未注册,则在程序门户网站注册一个通配符应用程序标识符。
3)为该通配符应用程序标识符创建一个分发设置配置文件,将它命名为易于标识的名称(例如My Wildcard DistributionProfile)。下载它,然后添加到Xcode中,方法是将它拖到Xcode应用程序图标上或Organizer窗口中。
4)打开ProjectInfo窗口(Cmd+I)。在Configurations选项卡中选择Release。单击Duplicate并将新副本命名为Distribution。这个新的分发配置将存储所有必需的信息,用意创建兼容AppStore的版本。完成创建之后,可以在Debug、Release和Distribution配置文件之间进行切换,他们将记住自己的设置。记住只需要在两个位置设置配置:主项目窗口和TargetInfo窗口。
5)关闭Project Info窗口。在主项目窗口中,从Active BuildConfiguration弹出菜单中选择Distribution。这是第一个需要设置构建配置的地方。
6)打开Target Info窗口并选择Build选项卡。
7)在TargetInfo,Build窗口中,从Configuration弹出菜单中选择Distribution,这是第二个需要配置的地方。
8)在Code Signing Identity下,将iPhone Developer修改为iPhoneDistribution。
9)从Code Signing Provisioning Profile弹出菜单中选择新通配符分发配置文件。
10)构建项目。然后,选择Groups&Files,ProjectName,Products,Application Name,Reveal in Finder,查找最新创建的应用程序束。
通过这些步骤,可以构建程序的分发版本。构建项目之后,可以压缩新束并将它提交到App Store。
1.12 使用文档中未记录的API调用
按官方说法,苹果公司禁止使用文档中未记录的API调用。如果希望应用程序符合AppStore限制,应不使用任何未发布的东西。而非正式的情况下,苹果公司的一贯策略是可以使用公共框架中任何API,只要你愿意承担程序可能在苹果公司发布新操作系统更新时无法运行的风险。这种非正式的策略目前已延伸到iPhone。只要公共框架中有,你就可以使用,但是,你必须自己承担可能出现的后果。
本书多处采用了这种开放式访问的方式。文档中未记录的调用在本书中随处可见,尤其是第四章。每一处应用都有标记。所有使用文档中未记录的调用的地方都提供了明确的说明。
同时,本书还是有自己的规则的。
1)私有框架我们不碰。只链接和访问出现在Apple-sanctioned Frameworks文件夹中的公共项。
2)不必运行守护进程。所有代码都在主应用程序中执行。
3)必须在iPhone表示拒绝时退出。代码遵守苹果公司一段时间只运行一个应用程序的策略。
4)不能使用插件或执行任意代码。苹果公司和App Store支持所有代码。
5)沙盒就是沙盒。本书从未提过如何访问私有区域,如机载iTunes Media文件夹。
遵章守纪的计算并不意味着大受局限的计算。如果你更愿意避免文档中未记录的API调用,本书介绍的绝大多数技巧仍然可以为iPhone开发体验增加乐趣的新鲜感。
1.13 临时分发
苹果公司允许通过临时(Ad Hoc)分发在AppStore外部分发应用程序。通过临时分发,可以将应用程序发送到最多100个注册设备,并使用一种特殊的移动设置(允许应用程序在iPhone的FairPlay限制下执行)来运行这些应用程序。临时分发对于Beta测试以及向新闻和刊物网站提交审查应用程序极为有用。
首先注册设备。使用iPhone Developer Program Portal注册设备标识符(ProgramPortal,Devices)。直接从iPhone(使用第九章中的UIDevice调用)、ITunes(单击iPhone的Summary选项卡上的SerialNumber)或System Profiler(选择USB,iPhone,SerialNumber)恢复这些标识符。输入标识符和唯一的用户名。
接下来,构建设置。要构建移动设置,选择Program Portal,Provisioning,Distribution。单击AddProfile,然后选择AdHoc,输入配置文件名称、标准通配符应用程序标识符(如com.yourname.*),并选择要部署的一个或多个设备。单击Submit并等待苹果公司构建新移动设置。然后下载设置文件,将它拖放到Xcode中。你将使用它构建应用程序。
需要在Ad Hoc项目中添加一个特殊的权限文件。在Xcode中,选择File,New File,CodeSigning,Entitlements。单击Next。新建一个名称为dist.plist的权限文件。单击Finish。权限属性列表将出现在Products文件夹中。双击打开该列表并取笑选中get-task-allow(也就是将它设置为FALSEBoolean值)。
设置权限之后,需要将它添加到目标设置中。从项目窗口中选择Distribution配置。双击项目目标(Targets>项目名称),此时将打开TargetInfo窗口。在Build选项卡中,再次将配置设置为Distribution(如果尚未设置)。双击Code SigningEntitlements。在Code Signing Entitlements中添加文件名dist.plist并单击OK。
现在,你已经可以开始构建应用程序了。确保已将Code Signing Identity设置为iPhoneDistribution。从Any iPhone OSDevice弹出菜单中选择新的临时移动设置。选择Build,Clean(Cmd+Shift+K),然后选择Build,Build(Cmd+B)构建项目。从项目窗口的Products文件夹中选择最新编译的产品。右键单击它并选择Revealin Finder。将打开一个Finder窗口,其中显示了编译后的项目。
分发此应用程序的一个副本,刚才你已通过移动临时设置以及从苹果公司下载的设置编译了该应用程序。用户可以将设置和应用程序拖到iTunes中,然后再让应用程序保持与自己的iPhone同步。应用程序将仅在这些注册过的电话上运行,这提供了一种直接向用户分发应用程序的安全方式。
1.14 小结
本章介绍了iPhone应用程序,如何构建它以及如何通过少许步骤构建基本的HelloWorld程序。最后,我们来回顾一下本章的要点:
1)下载和安装SDK以及构建和测试第一个应用程序应能在数小时内完成。
2)iPhone应用程序束比他在Macintosh上的对等应用程序更加简单,但他们有许多共同特性,包括Info.plist和lproj文件夹。
3)iPhoneSDK要求只在有线缆连接的设备上进行测试。WiFi测试尚不可用。尽管如此,Xcode中的Organizer提供了极好的组织功能,可通过其控制台、故障日志和屏幕快照测试应用程序。
4)具有Cocoa经验的开发人员就足以创建iPhone应用程序。熟悉Obj-C和Cocoa最佳实践的开发人员会具备良好的开发基础。