关于iOS App Programming

1、App Design Basics
2、Core App Objects
html

 
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对象:

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

NSInteger/NSUInteger
NSRange
NSTimeInterval
CGPoint
CGSize
CGRect

二、用户界面
三、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:查找资源路径

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

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

 
二、应用加载周期:
git

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

三、进入到后台:
你的代理applicationDidEnterBackground:有5秒的事件来结束任务并返回。实际上,这个方法应该尽快的返回。若是在规定时间内没有返回,你的应用会被kill掉并清除出内存。若是你须要更多的时间来执行任务,调用 beginBackgroundTaskWithExpirationHandler:方法来请求后台执行时间,并在另外一个线程中执行长时间的耗时任务
四、在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

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

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

九、在后台执行一个有限长度的任务(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;
    });
}

十、安排本地通知
十一、实现长时间的耗时后台任务:
对于须要更多执行时间的任务来讲,你必须请求特定的权限来在后台执行他们。在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

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

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

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

1四、在后台播放音乐
1五、实现一个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了)


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

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

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

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

6、高级App 技巧:
一、建立一个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文件:

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

八、与其余应用交互:
支持自定义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。

九、实现自定义的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;
}

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

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

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

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

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

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

相关文章
相关标签/搜索