iOS App Programming

来源:互联网 发布:淘宝上可以贷款吗 编辑:程序博客网 时间:2024/05/17 03:32

一、App Design Basics
二、Core App Objects

 
1)UIApplication对象:管理应用事件loop和协调行为。你在appDelegate中可以用到它,或者通过[UIApplication sharedAppliation]得到。
2)App Delegate 对象: 在创建应用时候创建的自定义对象,一般通过UIApplicationMain函数创建。这个对象的主要任务是处理应用状态的改变。
3)Document和data模型对象: document对象是UIDocument的子类来管理数据模型对象(相当于数据库吧)。Document对象不是必须的,但是提供了一种便利的方法,让你在一个单独的文件或文件包中管理数据。(本人用的数据库较多,对UIDocument研究甚少)
4)View Controller对象:
5)UIWindow对象:
6)视图、control和layer对象:

1、数据模型:
NSString、NSAttributedString
NSNumber、NSDecimalNumber、NSIndexPath
NSData、NSValue
NSDate、NSDateComponents
NSURL
NSArray、NSDictionary、NSIndexSet、NSOrderedSet、NSSet

NSInteger/NSUInteger
NSRange
NSTimeInterval
CGPoint
CGSize
CGRect

2、用户界面
3、App Bundle包括:
1)App执行文件
2)Info.plist
3)App Icons: icon.png、icon@2x.png、icon-small.png、icon-small@2x.png
4)Launch images:Default.png、Default-portrait.png、Default-Landscape.png
5)storyboard files(或者nib files): Mainboard.storyboard(通过NSMainStoryboardFile指定)或mainWindow.xib(通过NSMainNibFile指定)
6)Ad hoc distribution icon:文件名必须为iTunesArtwork,且不能包含扩展名: 512*512pixel,对于ad hoc发布来说是必须的,但是对于其他来说是可选的
7)Setting Bundle:Settings.bundle:如果你想在Settings App中设置你的应用的自定义设置,你必须提供一个setting bundle。
8)非本地化的资源文件:
9)本地化资源:例如en.lproj、fr.lproj

使用[NSBundle mainBundle]获得bundle资源,使用pathForResource:ofType:查找资源路径

三、App状态和多任务
对于iOS应用来说,知道应用运行于前台还是后台是至关重要的。因为资源和性能。
在你实现你的应用时,遵循下面的指导:
1)(必须) 正确响应状态变化。
2)(必须)当进入到后台,确保你的应用正确地调整了行为。
3)(推荐)注册系统通知来响应状态变化。
4)(可选)如果你的应用需要在后台做一些实际的工作,请求系统合适的权限来继续运行。

1、管理状态变化:
1)Not Running
2)Inactive:在前台,但是不接收事件。一个应用一般只会在状态发生改变时才会经过这个状态。
3)Active
4)Background:在后台并执行代码中。一般只会在应用转到Suspended状态过程中经过这个状态。然而,应用可以请求额外的执行时间,这可能会让应用在这个状态保留一段时间。另外,一个正在加载的应用直接进入到这个状态而不是Inactive状态。
5)Suspended:在后台并且不执行代码。

 
2、应用加载周期:

 
要确定你的应用在前台还是后台,可以请求[UIApplication sharedApplication]的applicationState属性。当你的应用被加载到前台时,其状态是UIApplicationStateInactive(中间状态),当你的应用被加载到后台时,属性为UIApplicationStateBackground。你可以使用这个差别来调整加载时的行为----在application:didFinishLaunchingWithOptions:方法中。

3、进入到后台:
你的代理applicationDidEnterBackground:有5秒的事件来结束任务并返回。实际上,这个方法应该尽快的返回。如果在规定时间内没有返回,你的应用会被kill掉并清除出内存。如果你需要更多的时间来执行任务,调用 beginBackgroundTaskWithExpirationHandler:方法来请求后台执行时间,并在另一个线程中执行长时间的耗时任务
4、在Wakeup时处理Queued Notifications:
在Suspended状态的应用必须准备好处理任何queued通知---当其返回到前台或后台执行状态。Suspended状态的app不执行任何代码,因此不能处理通知,包括设备方向更改、Preferences更改,和其他可能影响应用界面或状态的通知。为了确保这些更改不丢失,系统queue了尽可能多的这些通知,并在应用返回前台时通知应用。
你可以注册很多通知,包括:
1)配件连接了或断开了:EAAccessoryDidConnectNotification、EAAccessoryDidDisconnectNotification
2)设备方向更改: UIDeviceOrientationDidChangeNotification
3)显著的时间更改:UIApplicationSignificantTimeChangeNotification
4)电池电量状态更改:UIDeviceBatteryLevelDidChangeNotification、UIDeviceBatteryStateDidChangeNotification
5)The proximity state changes:UIDeviceProximityStatDidChangeNotification
6)受保护的文件状态更改:UIApplicationProtectedDataWillBecomeUnavailable、UIApplicationProtectedDataDidBecomeAvailable
7)外部显示器连接或断开:UIScreenDidConnectNotification、UIScreenDidDisconnectNotification
8)屏幕显示模式更改:UIScreenModeDidChangeNotification
9)Preference更改:NSUserDefaultsDidChangeNotification
10)当前语言更改:NSCurrentLocaleDidChangeNotification

5、在应用进入到Suspended状态后,如果下面的某一项为真,那么程序会退出:
1)应用linked against iOS 4.0以前。
2)应用发布到iOS4.0以前的设备上。
3)当前设备不支持多任务(multitasking)
4)应用在info.plist中包括键UIApplicationExitsOnSuspend。

6、Main Run Loop:
7、后台执行和Multitasking:
8、确定Mulititasking是否可用:
UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:@selector(isMultitaskingSupported)])
   backgroundSupported = device.multitaskingSupported;

9、在后台执行一个有限长度的任务(Finite-Length Task):
beginBackgroundTaskWithExpirationHandler: ,还必须相应地调用endBackgroundTask:方法来标识任务结束(好吧,不调用endBackgroundTask:也可以,只需要调用beginBackgroundTaskWithExpirationHandler就可以让系统给你10分钟免费的后台时间)。(系统给额外的10分钟让你执行任务!!!)
例子:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        // Clean up any unfinished task business by marking where you.
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];
 
    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 
        // Do the work associated with the task, preferably in chunks.
 
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

10、安排本地通知
11、实现长时间的耗时后台任务:
对于需要更多执行时间的任务来说,你必须请求特定的权限来在后台执行他们。在IOS中,只有特定的应用类型才允许在后台运行:
1)应用播放音频内容
2)应用实时保持通知他们的位置,例如导航应用。
3)应用支持Voice over Internet Protocol (VoIP)
4) Newsstand apps that need to download and process new content
5) Apps that receive regular updates from external accessories

12、声明你的应用支持的后台任务:
使用info.plist文件。添加UIBackgroundModes键并设置其值为一个数组,包含一个或多个字符串:
1)audio
2) location
3) voip

4) newsstand-content
5) external-accessory
6) bluetooth-central

13、跟踪用户的位置
有几种办法跟踪用户位置,大多数不需要你的应用在后台持续运行:
1)(推荐)显著的位置更改服务
2)只在前台运行的位置服务
3)后台位置服务
在你不需要高精度定位时,第一个方法是极力被推荐的。在第一个方法中,如果应用被挂起了,然后更新发生了,系统会唤醒其到后台状态并处理更新。如果应用开启了服务然后被结束掉了,系统会自动重新启动应用。
第二个方法和第三个方法都是用标准的Location Core Service来获取位置数据。唯一的区别是只在前台运行的位置服务在应用挂起时会停止投递更新,一般发生于应用不支持其他后台服务或任务。
通过前面介绍的UIBackgroundModes键指定location,就可以让应用在后台接收更新。注意这个键并不阻止系统挂起应用,但是它确实告诉系统它应该被唤醒。但是这个比较费电。

14、在后台播放音乐
15、实现一个VoIP应用:
1)UIBackgroundModes键指定数组中包含voip字符串。
2)配置app为voip而使用的socket
3)在进入到后台时,调用setKeepAliveTimeout:handler:
4)配置audio session来处理实际使用的转换。
5)为了确保一个好的用户体验,使用Core Telephony框架,在有电话时调整应用的行为
6)为了确保一个好的性能,使用SystemConfiguration框架来检测网络状态的变化,并且允许应用尽可能地睡眠。

配置了UIBackgroundModes为voip之后,不用再指定audio 也可以在后台播放音乐。
指定了voip之后的应用也会在系统启动后立即加载到后台

配置socket:
对于NSInputStream和NSOutputStream:使用setProperty:forKey:方法来添加NSStreamNetworkServiceType属性为NSStreamNetworkServiceTypeVoIP。
对于NSURLRequest:使用NSMutableURLRequest类实例的setNetworkServiceType:方法,参数为NSURLNetworkServiceTypeVoIP
对于CFReadStreamRef和CFWriteStreamRef:使用CFReadStreamSetProperty或 CFWriteStreamSetProperty函数来添加kCFStreamNetworkServiceType属性,这个属性的值应该是kCFStreamNetworkServiceTypeVoIP。

因为VoIP应用需要保持运行,以便接收来电,如果他以一个非0值退出,系统会自动将其重新载入。

使用[UIApplication sharedApplication] setKeepAliveTimeout:handler:来为应用添加一个Keep-Alive Handler,一般在applicationDidEnterBackground:方法中添加它。一般安装了Handler,系统会在timeout之前至少调用一次handler,handler有10s的运行时间,否则系统会挂起应用。
指定timeout的时候,一般指定为实际允许的最大值,虽然系统承诺在timeout之前调用你的handler块,但他不保证精确的调用时间。为了提高电池寿命,系统一般把你的handler块执行代码和其他周期性的系统任务放到一个组里,然后一次性处理所有的任务。因此,您的Handler代码必须准备好运行早于实际的你指定的Timeout。(也就是如果你需要10s的timeout值,那么你就指定5s就OK了)


五、App相关的资源
1、App Store必须的资源:
1) Info.plist文件。
2) Info.plist文件必须包含 UIRequiredDeviceCapabilities键。App商店使用这个键来确定一个用户是否可以在设备上运行你的应用。
3)你的应用必须包含一个或多个icons。
4)你的应用必须包含一个default.png。

2、Info.plist文件
1)UIRequiredDeviceCapabilities 键
2)CFbundleIcons:
3) UISupportedInterfaceOrientations

4)UIBackgroundModes:
5)UIFileSharingEnabled:
6) UIRequiresPersistentWifi
7)UINewsstandApp:

3、声明UIRequiredDeviceCapabilities :
这个键对应一个字典的数组
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/App-RelatedResources/App-RelatedResources.html

六、高级App 技巧:
1、创建一个Universal应用:
1)更新Info.plist设置:
key_root-<platform>~<device>
device有
    iphone—The key applies to iPhone devices.
    ipod—The key applies to iPod touch devices.
    ipad—The key applies to iPad devices.
例如:
UIInterfaceOrientation~ipad

2)实现你的试图控制器和视图:
3)为新的Symbols添加Runtime检查:
4)使用Runtime检查来创建条件的代码路径:
5)更新你的Resource文件:

2、保留应用用户界面的状态:
3、在Landscape模式下加载应用:
4、在第一次加载时安装应用特定的数据文件
5、保护数据使用On-Disk加密
6、开发VoIP App的技巧:
7、使用Reachability界面来改善用户体验:
Reachability interface允许应用在网络状态更改时得到通知。例如,一个VoIP应用可以在网络变得不可用时关闭网络链接并且在其变得可用时恢复网络链接。
要使用Reachability interface,你必须使用该框架注册一个回调函数并使用它来追踪网络变化。要注册一个回调函数:
1)为你的目标远程主机创建一个SCNetworkReachabilityRef结构。
2)指定一个回调函数到你的结构(使用 SCNetworkReachabilitySetCallback函数)来处理可达状态的变化。
3)添加那个目标到你的应用的一个active run loop(例如Main Run Loop),使用 SCNetworkReachabilityScheduleWithRunLoop函数。
这也提升了电池的寿命。

8、与其他应用交互:
支持自定义URL scheme的应用可以使用这些schemes来接收消息。一些应用使用URL Scheme来初始化特定的请求。例如,一个应用想在地图应用中显示一个地址,可以使用一个URL来加载那个应用并显示地址。你可以在你的应用中实现你自己的URL Scheme来促进类似的通信类型。
Apple提供了一些内建的URL Scheme支持,如http,mailto,tel和sms URL Schemes。它还支持针对地图的基于http的URL、YouTube和iPod Apps。这些Schemes的handler被固定并且不能更改。如果你的URL type包含apple提供的url scheme,Apple提供的应用会加载而不是你的应用。
注意:如果不只一个第三方app注册了相同的URL scheme,当前没有办法来决定哪个app会收到scheme。
要与一个使用自定义URL的app通信,要使用正确的格式内容创建一个NSURL对象,并传递这个对象给shared UIApplication的openURL:方法,来加载注册接收该URL类型的应用。那时,控制也交给了新的app。
下面的代码片段例示了一个应用如何请求另一个应用的服务。(例子中的"todolist"是另一个app的一个假设的自定义的url scheme):
NSURL *myURL=[NSURL URLWithString:@"todolist://www.acme.com?Quartery%20Report#200806231300"];
[[UIApplication sharedApplication] openURL:myURL];
如果你的应用定义了一个自定义的URL Scheme,你需要实现一个handler来处理scheme。

9、实现自定义的URL Schemes:
1)注册自定义的URL Schemes:在Info.plist文件中指定CFBundleURLTypes键。它是一个字典的数组,每个字典定义了一个URL scheme。
CFBundleURLTypes(在info.plist中为URL types)属性包含的字典的键和值
键 CFBundleURLName(在info.plist中为URL identifier)   为:一个包含URL scheme抽象名字的字符串。为了确保唯一性,推荐你指定一个反向DNS风格的标识符,例如:com.acme.myscheme。
键 CFBundleURLSchemes(在Info.plist中为URL scheles)  为:一组字符串,包含URL schemes的名字,例如:http、mailto、tel和sms等

 
上面图中的例子就是该应用支持 todolist://com.acme.ToDoList 格式的URL。

2)处理URL Requests:
所有的URLs被传递给你的应用Delegate,或者在加载时,或者你的应用已经运行或在后台时。要处理传进的URLs,你的应用代理应该实现下面的方法:
a)使用application:didFinishLaunchingWithOptions:方法来检索关于URL的信息并决定如何打开它。这个方法只在你的应用被加载时调用。
b)在iOS 4.2以后,使用application:openURL:sourceApplication:annotation:方法来打开文件。
c)在iOS 4.1以前,使用application:handleOpenURL:方法来打开文件。

如果URL请求到来时,你的应用没有运行,它被加载并移动到前台来使其能够打开URL。你的application:didFinishLaunchingWithOptions:实现方法应该从options字典中检索URL并决定应用是否能够打开它。如果可以打开,返回YES并使你的application:openURL:sourceApplication:annotation:(或application:handleOpenURL:)方法来处理实际的打开URL的操作。
下图显示了如果应用打开一个URL时 修改后的加载顺序:

 
注意:支持自定义URL scheme的应用可以指定不同的Launch图像,在加载时处理URL时显示。

例子:
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
  if ([[url scheme] isEqualToString:@"todolist"]){
   ToDoItem *item=[[ToDoItem alloc]init];
   NSString *taskName=[url query];
   if (!taskName || ![self isValidTaskString:taskName]){  //必须要有一个TaskName
       [item release];
       return NO;
   }
   taskName=[taskName stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

   item.toDoTask=taskName;
   NSString *dateString=[url fragment];
   if (!dateString || [dateString isEqualToString:@"today"]){
     item.dateDue=[NSDate date];
   } else {
     if (![self isValildDateString:dateString]){
       [item release];
       return NO;
    }
           NSString *curStr = [dateString substringWithRange:NSMakeRange(0, 4)];
            NSInteger yeardigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(4, 2)];
            NSInteger monthdigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(6, 2)];
            NSInteger daydigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(8, 2)];
            NSInteger hourdigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(10, 2)];
            NSInteger minutedigit = [curStr integerValue];
 
            NSDateComponents *dateComps = [[NSDateComponents alloc] init];
            [dateComps setYear:yeardigit];
            [dateComps setMonth:monthdigit];
            [dateComps setDay:daydigit];
            [dateComps setHour:hourdigit];
            [dateComps setMinute:minutedigit];
            NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
            NSDate *itemDate = [calendar dateFromComponents:dateComps];
            if (!itemDate) {
                [dateComps release];
                [item release];
                return NO;
            }
            item.dateDue = itemDate;
            [dateComps release];
        }
 
        [(NSMutableArray *)self.list addObject:item];
        [item release];
        return YES;
    }
    return NO;
}

10、显示和隐藏键盘
在UIKit中,只有支持文本输入的视图才能成为第一响应者。其它视图如果想可以成为第一响应者并显示键盘,那么它必须重载canBecomeFirstResponder方法并返回YES。
当一个视图变成第一响应者时,会默认显示键盘,但是你可以为支持自定义输入的视图替换键盘。每个responder都有一个inputView属性,它包含响应者成为第一响应者时显示的view。当这个属性为nil时,系统显示标准键盘。如果这个属性不为nil,系统显示你提供的视图。

一般,用户的轻击命令哪个视图变成第一响应者,但是你可以强制一个视图变成第一响应者。使用becomeFirstResponder方法。

11、取消屏幕锁定
设置shared Application的idleTimerDisabled属性为YES,让屏幕不锁定。为NO,则不阻止屏幕锁定。

七、提升性能:
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/PerformanceTuning/PerformanceTuning.html

八、iOS环境
1、特定的系统行为:
1)虚拟的内存系统
2)自动的睡眠Timer
3)多任务支持

2、安全
1)App Sandbox
2)Keychain Data

0 0
原创粉丝点击