天天看點

iOS6、7、8、9新特性彙總和适配說明

一、關于記憶體警告ios6中廢除了viewDidUnload,viewWillUnload這兩個系統回調,收到記憶體警告時在didReceiveMemoryWarning中進行相關的處理。

二、關于螢幕旋轉同樣ios6 廢除了shouldAutorotateToInterfaceOrientation這個旋轉螢幕的設定接口。必須在兩個新接口中設定旋轉屬性:shouldAutorotate、supportedInterfaceOrientations。收到旋轉事件後的處理,同樣在willRotateToInterfaceOrientation和didRotateFromInterfaceOrientation中進行。

三、UISwitchios6下,新增了以下幾個屬性,可以設定開關的顔色以及背景圖。@property (nonatomic,  retain) UIColor *tintColor;

 @property (nonatomic,  retain) UIColor *thumbTintColor; 

@property (nonatomic,  retain) UIImage *onImage; 

@property (nonatomic,  retain) UIImage *offImage;

四、UINavigationBarios6新增了,設定陰影圖檔的屬性。

[email protected] (nonatomic, retain) UIImage *shadowImage;

五、UIImage可以在ios6下設定圖檔的scale比例尺寸了。

+ (UIImage *)imageWithData:(NSData *)data scale:(CGFloat)scale; 

- (id)initWithData:(NSData *)data scale:(CGFloat)scale;

六、UIRefreshControl之前蘋果官方是沒有現成的下拉重新整理的控件,都是自己實作或者使用比較成熟的開源庫。ios6蘋果加入了UIRefreshControl,配合UITableView直接實作下拉重新整理。

七、UICollectionView全新的集合控件,應用場景有類似照片牆,瀑布流等。

iOS7新特性

一、已禁用-[UIDevice uniqueIdentifier]蘋果總是把使用者的隐私看的很重要。

-[UIDevice uniqueIdentifier]在iOS5實際在iOS5的時候已經被遺棄了,但是iOS7中已經完全的禁用了它。Xcode5甚至不會允許你編譯包含了指引到-[UIDevice uniqueIdentifier]的app。此外,iOS7之前的使用了-[UIDevice uniqueIdentifier] 的app如果在iOS7上運作,它不會傳回裝置的UUID,而是會傳回一串字元串,以FFFFFFFF開頭,跟着-[UIDevice identifierForVendor]的十六進制值。

二、UIPasteboard由共享變為沙盒化了UIPasteboard過去是用來做app之間的資料分享的。UIPasteboard本無問題,但是開發者開始使用它來存儲辨別符,和其他的相關app分享這些辨別符的時候問題就出現了。有一個使用這種把戲的就是OpenUDID。在iOS7中,使用

+[UIPasteboard pasteboardWithName:create:]和 

+[UIPasteboard pasteboardWithUniqueName]建立剪貼闆,而且隻對相同的app group可見,這樣就讓OpenUDID不那麼有用了。

三、MAC位址不能再用來設别裝置還有一個生成iOS裝置唯一标示符的方法是使用iOS裝置的Media Access Control(MAC)位址。一個MAC位址是一個唯一的号碼,它是實體網絡層級方面配置設定給網絡擴充卡的。這個位址蘋果還有其他的名字,比如說是硬體位址(Hardware Address)或是Wifi位址,都是指同樣的東西。有很多工程和架構都使用這個方法來生成唯一的裝置ID。比如說ODIN。然而,蘋果并不希望有人通過MAC位址來分辨使用者,是以如果你在iOS7系統上查詢MAC位址,它現在隻會傳回02:00:00:00:00:00。現在蘋果明确的表明你應該使用

-[UIDevice identifierForVendor]或是-[ASIdentifierManager advertisingIdentifier]來作為你架構和應用的唯一标示符。坦白的來說,應對這些變化也不是那麼的難,見以下代碼片段:123NSString *identifierForVendor = [[UIDevice currentDevice].identifierForVendor UUIDString]; NSString *identifierForAdvertising = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];每種方法都适配一種特别的用法:identifierForVendor對供應商來說是唯一的一個值,也就是說,由同一個公司發行的的app在相同的裝置上運作的時候都會有這個相同的辨別符。然而,如果使用者删除了這個供應商的app然後再重新安裝的話,這個辨別符就會不一緻。advertisingIdentifier會傳回給在這個裝置上所有軟體供應商相同的 一個值,是以隻能在廣告的時候使用。這個值會因為很多情況而有所變化,比如說使用者初始化裝置的時候便會改變。

四、iOS現在要求app如需使用麥克風,需要征得使用者同意以前如果app需要使用使用者的位置,通訊錄,月曆,提醒以及照片,接受推送消息,使用使用者的社交網絡的時候需要征得使用者的同意。現在在iOS7當中,使用麥克風也需要取得使用者同意了。如果使用者不允許app使用麥克風的話,那麼需要使用麥克風的app就不能接收不到任何聲音。以下的代碼是用來查詢使用者是否允許app使用麥克風

//第一次調用這個方法的時候,系統會提示使用者讓他同意你的app擷取麥克風的資料/

/ 其他時候調用方法的時候,則不會提醒使用者// 而會傳遞之前的值來要求使用者同意[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted)

 {    if (granted) {        

// 使用者同意擷取資料    } else {       

 // 可以顯示一個提示框告訴使用者這個app沒有得到允許?    }}];你同時還要注意,如果你在獲得使用者的同意之前使用任何方法來使用麥克風的話,會引起iOS系統彈出以下警示欄:

iOS6、7、8、9新特性彙總和适配說明

五、[NSArray firstObject]的實作-[NSArray firstObject]可能是Objective-C中被調用做多的API。在Open Radar上一個簡單的調查顯示有一些需求蘋果已經做了記錄。好消息是現在這些需求已經得到了解決。. firstObject的使用可以追溯到iOS4.0,但是那時僅僅是一個私有方法。在iOS7以前,工程師用下面的方式來使用它:12345NSArray *arr = @[];id item = [arr firstObject]; // 在之前你需要做以下工作id item = [arr count] > 0 ? arr[0] : nil;因為上面的方式很平常,有些人将它作為一個類增加到NSArray中,然後建立他們自己的firstObject方法。這個方法的問題是這個方法的名字必須是唯一的,否則的話這個方法所引發的問題無法預估。請確定檢查你是否有任何自定義的代碼在NSArray上實作了firstObject,如果有的話看看它是否是必須的,不是必須的話就把它全部移除。

六、增加了instancetypeinstancetype讓iOS7API變得更加難懂。蘋果改變了大部分 initializer和簡易構造函數(convenience constructors),用instancetype代替id作傳回類型。但是這個instancetype是什麼呢?instancetype用來在聲明一個方法時告訴編譯器其傳回類型,它表示傳回調用該方法的類的對象。這比之前傳回id的通常做法要好,編譯器可以對傳回類型做一些檢查,如果出現錯誤,在編譯時就能提醒你,而不是在程式運作時發生崩潰。同時,在調用子類方法時,使用它還可以省去對傳回值的強制類型轉換,編譯器能夠正确推斷方法的傳回值類型。要說到instancetaype的缺點和優點嗎?基本上,在任何可能的情況下都可以使用它。

七、設定UIImage的渲染模式:UIImage.renderingMode着色(Tint Color)是iOS7界面中的一個重大改變,你可以設定一個UIImage在渲染時是否使用目前視圖的Tint Color。UIImage新增了一個隻讀屬性:renderingMode,對應的還有一個新增方法:imageWithRenderingMode:,它使用UIImageRenderingMode枚舉值來設定圖檔的renderingMode屬性。該枚舉中包含下列值:12345678// 根據圖檔的使用環境和所處的繪圖上下文自動調整渲染模式UIImageRenderingModeAutomatic  // 始終繪制圖檔原始狀态,不使用Tint ColorUIImageRenderingModeAlwaysOriginal  // 始終根據Tint Color繪制圖檔,忽略圖檔的顔色資訊UIImageRenderingModeAlwaysTemplaterenderingMode屬性的預設值是UIImageRenderingModeAutomatic,即UIImage是否使用Tint Color取決于它顯示的位置。其他情況可以看下面的圖例:

iOS6、7、8、9新特性彙總和适配說明

以下的代碼說明了使用一個既定的rendering模式建立圖檔是多麼簡單:123UIImage *img = [UIImage imageNamed:@"myimage"]; img = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];八、tintcolor VS barTintColoriOS7中你可以使用一個給定的顔色,甚至是記入顔色主題來給整個app着色,幫助你的app脫穎而出。設定app的tint color很簡答,隻要使用UIView的新屬性tintColor即可。這個屬性是否聽上去很熟悉呢?應該很熟悉,有些類,比如說UINaviagtionBar,UISearchBar,UITabBar以及UIToolbar已經有了這麼命名的屬性。他們現在有了一個新的屬性:barTintColor。為了避免使用新屬性的時候犯錯誤,如果你的appp需要支援iOS6以前的系統的時候,請檢查一下。12345678UINavigationBar *bar = self.navigationController.navigationBar;UIColor *color = [UIColor greenColor]; if ([bar respondsToSelector:@selector(setBarTintColor:)]) { // iOS 7+    bar.barTintColor = color;} else { // what year is this? 2012?    bar.tintColor = color;}

九、去掉了紋理顔色

iOS6、7、8、9新特性彙總和适配說明

紋理顔色?對,不再使用他們了,不能再建立可以展現紋理的顔色。根據UIInterface.h檔案中的注釋,-[UIColor groupTableViewBackgroundColor]應該是要在iOS6當中即被删除了,但是它僅僅隻是不像之前那樣傳回紋理顔色了。然而,以下的顔色在iOS7當中被删除了:12345+ (UIColor *)viewFlipsideBackgroundColor; + (UIColor *)scrollViewTexturedBackgroundColor; + (UIColor *)underPageBackgroundColor;

十、UIButtonTypeRoundRect被UIButtonTypeSystem取代了4673_140117110855_1

iOS6、7、8、9新特性彙總和适配說明

在iOS開發剛開始就陪伴着你的老朋友現在也被删除了,它就是UIButtonTypeRoundRect ,被新的UIButtonTypeSystem取代了。如果每次iOS系統的釋出都沒有一些新的功能會是什麼樣子?這些新功能相信大部分開發者已經知道了,你可能會發現一些新穎的方式将它們整合到你的app中去!

十一、檢查無線路由是否可用定制一個視訊播放器的能力在iOS版本每次的釋出中一直有所進步。比如說,在iOS6之前,你不能在MPVolumeView中改變AirPlay的icon。在iOS7當中,你可以通過AirPlay,藍牙或是其他的虛線機制了解是否有一個遠端的裝置可用。了解它的話,就可以讓你的app在恰當的時候做恰當的事,比如說,在沒有遠端裝置的時候就不顯示AirPlay的icon。以下是新增加到MPVolumeView的新屬性和推送1234

@property (nonatomic, readonly) BOOL wirelessRoutesAvailable; //  是否有裝置可以連接配接的無線線路?@property (nonatomic, readonly) BOOL wirelessRouteActive; // 裝置現在是否連接配接上了網絡NSString *const MPVolumeViewWirelessRoutesAvailableDidChangeNotification;NSString *const MPVolumeViewWirelessRouteActiveDidChangeNotification;

十二、了解蜂窩網絡在iOS7之前,是使用Reachability來檢測裝置是否連接配接到WWAN或是Wifi的。iOS7在這個基礎上更進了一步,它會告訴你的裝置連接配接上的是那種蜂窩網絡,比如說是Edge網絡,HSDPA網絡,或是LTE網絡。告訴使用者他們連接配接上的是哪種網絡可以優化使用者體驗,因為這樣他們會知道網速如何,不會去請求需要高網速的網絡請求。這是CTTelephonyNetworkInfo的部分功能,它是CoreTelephony架構的一部分。iOS7還增加了currentRadioAccessTechnology屬性和CTRadioAccessTechnologyDidChangeNotification到這個類。還有一些新的字元串常量來定義可能的值,比如說是CTRadioAccessTechnologyLTE。以下代碼告訴你在app delegate中如何使用這個新功能:[email protected] CoreTelephony.CTTelephonyNetworkInfo; // new modules [email protected] AppDelegate ()// we need to keep a reference to the CTTelephonyNetworkInfo object, otherwise the notifications won't be [email protected] (nonatomic, strong) CTTelephonyNetworkInfo *networkInfo;@end @implementation ViewController - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   

 // whatever stuff your method does...        self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];    NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:    CTRadioAccessTechnologyDidChangeNotification object:nil];    

    // whatever stuff your method does...} - (void)radioAccessChanged {    NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology);} @end注意:研究一下CTTelephonyNetworkInfo.h 檔案來看看是否有其他無線網絡類型的的字元串常量。如果裝置沒有連上的話,currentRadioAccessTechnology 則會傳回nil。

十三、通過iCloud同步使用者裝置的密碼iOS7以及Mavericks增加了iCloud Keychain來提供密碼,以及iCloud中一些敏感資料的同步。開發者可以通過keychain中的kSecAttrSynchronizable key來周遊dictionary對象。由于直接處理keychain比較難,封裝庫提供了一個簡單的處理keychain的方法。SSKeychain封裝庫可能是最有名的的一個,作為一種福利,現在它支援在iCloud同步。以下代碼片段顯示了如何使用SSKeychain:

#import

- (BOOL)saveCredentials:(NSError **)error

 {    SSKeychainQuery *query = [[SSKeychainQuery alloc] init];    

query.password = @"MySecretPassword";   

 query.service = @"MyAwesomeService";    

query.account = @"John Doe";    

query.synchronizable = YES;    

return [query save:&error];}

 - (NSString *)savedPassword:(NSError **)error {    SSKeychainQuery *query = [[SSKeychainQuery alloc] init];    

query.service = @"MyAwesomeService";    

query.account = @"John Doe";    

query.synchronizable = YES;    

query.password = nil;   

 if ([query fetch:&error])

 {       

 return query.password;  

  }  

  return nil;}

不要忘記CocoaPods是快速便捷安裝SSKeychian的好方法。

十四、使用NSAttributedString顯示HTML在app中使用webview有時會讓人非常沮喪,即使隻是顯示少量的HTMLneirong ,webview也會消耗大量的記憶體。現在iOS7讓這些變得簡單了,你可以從用少量代碼在HTML檔案中建立一個NSAttributedString,比如:1234NSString *html = @"Wow!NowiOScan create

NSAttributedString

from HTMLs!";NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:nil error:nil];現在你可以在任意的UIKit對象上使用NSAttributedString 了,比如說是一個UILabel或是一個UITextField。注意:NSHTMLTextDocumentType 隻是NSDocumentTypeDocumentAttribute key一種可能的值。你還可以使用NSPlainTextDocumentType,NSRTFTextDocumentType或是NSRTFDTextDocumentType。你還可以從NSAttributedString中建立一個HTML字元串,如下:12345NSAttributedString *attrString; 

// from previous codeNSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; NSData *htmlData = [attrString dataFromRange:NSMakeRange(0, [attrString length]) documentAttributes:options error:nil];NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];現在你估計在app中會更多的使用HTML了。

十五、使用原生的Base64Base64是使用ASCII碼顯示二進制資料的一種流行方法。直到現在,開發者還不得不使用開源的工具來編碼解碼Base64的内容。現在iOS7引入了以下四種新的NSData方法來操作Base64編碼的資料:12345678// From NSData.h- (id)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options; - (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options; - (id)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options; 

- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options;這些方法可以幫助你輕易的将NSData對象轉化為Base64,或者将Base64轉化為NSData object。見以下的例子:1234567NSData* sampleData = [@"Some sample data" dataUsingEncoding:NSUTF8StringEncoding]; NSString * base64String = [sampleData base64EncodedStringWithOptions:0];NSLog(@"Base64-encoded string is %@", base64String);

 // prints "U29tZSBzYW1wbGUgZGF0YQ==" NSData* dataFromString = [[NSData alloc] initWithBase64EncodedString:base64String options:0];NSLog(@"String is %@",[NSString stringWithUTF8String:[dataFromString bytes]]);

 // prints "String is Some sample data"如果你需要支援iOS6或者更早以前的系統,你可以使用以下兩個方法:123456- (id)initWithBase64Encoding:(NSString *)base64String;- (NSString *)base64Encoding;

十六、使用UIApplicationUserDidTakeScreenshotNotification來檢查截圖在iOS7之前,像Snapshot或是Facebook Poke這樣的app是使用一些很精巧的方法來檢測使用者是否有截圖

。然而,iOS7提供一個嶄新的推送方法:UIApplicationUserDidTakeScreenshotNotification。隻要像往常一樣訂閱即可知道什麼時候截圖了。注意:UIApplicationUserDidTakeScreenshotNotification 将會在截圖完成之後顯示。現在在截圖截取之前無法得到通知。希望蘋果會在iOS8當中增加UIApplicationUserWillTakeScreenshotNotification。

十七、實作多語言語音合成如果可以讓app說話會不會很好呢?iOS7加入了兩個新類:AVSpeechSynthesizer 以及AVSpeechUtterance。這兩個類可以給你的app發聲。很有意思不是嗎?有多種語言可供選擇——Siri不會說的語言也有,比如說巴西葡萄牙語。使用這兩個類給app提供語言合成的功能非常簡單。AVSpeechUtterance 代表你想說什麼,如何說。AVSpeechSynthesizer 用來發出這些聲音,見以下代碼片段:

AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];AVSpeechUtterance *utterance =[AVSpeechUtterance speechUtteranceWithString:@"Wow, I have such a nice voice!"];utterance.rate = AVSpeechUtteranceMaximumSpeechRate / 4.0f;utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"]; 

// defaults to your system language[synthesizer speakUtterance:utterance];

十八、使用了新的UIScreenEdgePanGestureRecognizerUIScreenEdgePanGestureRecognizer 繼承自UIPanGestureRecognizer ,它可以讓你從螢幕邊界即可檢測手勢。使用新的手勢識别器很簡單,見以下:UIScreenEdgePanGestureRecognizer *recognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleScreenEdgeRecognizer:)];recognizer.edges = UIRectEdgeLeft;[self.view addGestureRecognizer:recognizer];

十九、使用UIScrollViewKeyboardDismissMode實作了Message app的行為像Messages app一樣在滾動的時候可以讓鍵盤消失是一種非常好的體驗。然而,将這種行為整合到你的app很難。幸運的是,蘋果給UIScrollView添加了一個很好用的屬性keyboardDismissMode,這樣可以友善很多。現在僅僅隻需要在Storyboard中改變一個簡單的屬性,或者增加一行代碼,你的app可以和辦到和Messages app一樣的事情了。這個屬性使用了新的UIScrollViewKeyboardDismissMode enum枚舉類型。

這個enum枚舉類型可能的值如下:UIScrollViewKeyboardDismissModeNone        // the keyboard is not dismissed automatically when scrollingUIScrollViewKeyboardDismissModeOnDrag      

// dismisses the keyboard when a drag beginsUIScrollViewKeyboardDismissModeInteractive 

// the keyboard follows the dragging touch off screen, and may bepulled upward again to cancel the dismiss以下是讓鍵盤可以在滾動的時候消失需要設定的屬性:

iOS6、7、8、9新特性彙總和适配說明

二十、使用Core Image來檢測眨眼以及微笑iOS給Core Image增加了兩種人臉檢測功能:CIDetectorEyeBlink以及CIDetectorSmile。這也就是說你現在可以在照片中檢測微笑以及眨眼。

以下是在app中使用它的方法:

UIImage *image = [UIImage imageNamed:@"myImage"];CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace                                          context:nil                                          options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}]; NSDictionary *options = @{ CIDetectorSmile: @YES, CIDetectorEyeBlink: @YES }; NSArray *features = [detector featuresInImage:image.CIImage options:options]; 

for (CIFaceFeature *feature in features) 

{   

 NSLog(@"Bounds: %@", NSStringFromCGRect(feature.bounds));        

if (feature.hasSmile)

 {        NSLog(@"Nice smile!");   

 } 

else

 {        NSLog(@"Why so serious?");   

 }   

 if (feature.leftEyeClosed || feature.rightEyeClosed) 

{        NSLog(@"Open your eyes!");    

}}

二十一、給UITextView增加了連結現在在iOS添加你自己的Twitter賬戶更加簡單了,現在你可以給一個NSAttributedString增加連結了,然後當它被點選的時候喚起一個定制的action。首先,建立一個NSAttributedString然後增加給它增加一個NSLinkAttributeName 屬性,NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:

@"This is an example by @marcelofabri_"];[attributedString addAttribute:NSLinkAttributeName                        value:@"username:

//marcelofabri_"                        range:[[attributedString string] rangeOfString:@"@marcelofabri_"]];  NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor greenColor],                                NSUnderlineColorAttributeName: [UIColor lightGrayColor],                                NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)}; 

// assume that textView is a UITextView previously created (either by code or Interface Builder)textView.linkTextAttributes = linkAttributes; 

// customizes the appearance of linkstextView.attributedText = attributedString;textView.delegate = self;這樣就可以讓連結在文本中顯示。然而,你也可以控制當連結被點選的時候會發生什麼,實作這個可以使用UITextViewDelegate協定的新的shouldInteractWithURL方法,就像這樣:123456789- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {    if ([[URL scheme] isEqualToString:@"username"]) {        NSString *username = [URL host];        // do something with this username        // ...        return NO;    }    return YES; // let the system open this URL}iOS8新特性一、UIAlertController對alert&actionSheet的封裝UIAlertController.h提示框按鈕的選擇123456789typedef NS_ENUM(NSInteger, UIAlertActionStyle) {        UIAlertActionStyleDefault = 0,        UIAlertActionStyleCancel,        UIAlertActionStyleDestructive    } NS_ENUM_AVAILABLE_IOS(8_0);提示框的樣式123456789typedef NS_ENUM(NSInteger, UIAlertControllerStyle) {        UIAlertControllerStyleActionSheet = 0,        UIAlertControllerStyleAlert    } NS_ENUM_AVAILABLE_IOS(8_0); NS_CLASS_AVAILABLE_IOS(8_0)

 @interface UIAlertAction : NSObject建立提示框按鈕1234567891011

+ (instancetype)actionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(UIAlertAction *action))handler; @property (nonatomic, readonly) NSString *title;

 @property (nonatomic, readonly) UIAlertActionStyle style; @property (nonatomic, getter=isEnabled) BOOL enabled; @end NS_CLASS_AVAILABLE_IOS(8_0)

 @interface UIAlertController : UIViewController建立提示框1

+ (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message preferredStyle:(UIAlertControllerStyle)preferredStyle;添加按鈕123

- (void)addAction:(UIAlertAction *)action;

 @property (nonatomic, readonly) NSArray *actions;添加文本輸入框123456789

- (void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler;

 @property (nonatomic, readonly) NSArray *textFields; @property (nonatomic, copy) NSString *title;

 @property (nonatomic, copy) NSString *message; @property (nonatomic, readonly) UIAlertControllerStyle preferredStyle;簡單實用示例:1234567891011

// 1.建立提示框對象,預設是actionSheet效果UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"注意" message:@"我的呈現方式變了" preferredStyle:UIAlertControllerStyleAlert];

 // 2.建立取消按鈕并添加到提示框上[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {        NSLog(@"取消按鈕被點選了");}]]; 

// 3.呈現提示框[self presentViewController:alert animated:YES completion:nil];

二、UIPopoverController直接通過present方式呈現UIViewController.h1234567891011121314151617181920212223typedef NS_ENUM(NSInteger, UIModalPresentationStyle)

 {       

 UIModalPresentationFullScreen = 0,        UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2),        UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2),        UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),        UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0),        UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0),        UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0),        UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0),        UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1,    }; @property (nonatomic,readonly) UIPopoverPresentationController *popoverPresentationController NS_AVAILABLE_IOS(8_0);使用示例:1234567891011// 1.建立内容控制器UITableViewController *contentVc = [[UITableViewController alloc] init]; 

// 2.1 設定呈現方式

contentVc.modalPresentationStyle = UIModalPresentationPopover; 

// 2.2設定在導航欄的左邊按鈕呈現contentVc.popoverPresentationController.barButtonItem = self.navigationItem.leftBarButtonItem; 

// 3.呈現[self presentViewController:contentVc animated:YES completion:nil];以前的方式:12345678910

// 1.建立内容控制器UITableViewController *contentVc = [[UITableViewController alloc] init]; 

// 2.建立popoverUIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:contentVc]; popover.popoverContentSize = CGSizeMake(100, 100);

 // 3.呈現[popover presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

三、擷取使用者授權的使用者隐私保護地圖定位示例 :1234567891011121314151617181920212223242526// 導入定位架構#[email protected] ViewController ()// 設定定位對象

@property(nonatomic,strong)CLLocationManager* maneger;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

// 當使用iOS8定位的時候需要請求使用者授權,且在info.plist裡添加字段NSLocationAlwaysUsageDescription 請求使用者授權的描述

// iOS7僅僅需要在info.plist裡添加字段Privacy - Location Usage Description 請求使用者授權的描述

// 不需要再寫下面的代碼

if (IOS8) {

[self.maneger requestAlwaysAuthorization];//請求使用者授權

}

// 開啟定位

[self.maneger startUpdatingLocation];

}

四、針對螢幕适配應運而生的size classes

size classes是為了解決storyboard隻能訂制一種螢幕樣式的問題,它不再是具體的尺寸,而是抽象尺寸通過寬/高 的compact、any、regular 組成了九種組合包含了所有蘋果裝置的尺寸。

iOS9新特性

一、網絡适配

iOS9系統發送的網絡請求将統一使用TLS 1.2 SSL。采用TLS 1.2 協定,目的是強制增強資料通路安全,而且系統Foundation架構下的相關網絡請求,将不再預設使用HTTP等不安全的網絡協定,而預設采用TLS 1.2。伺服器是以需要更新,以解析相關資料。如不更新,可通過在 info.plist 中聲明,倒退回不安全的網絡請求。

什麼是SSL/TLS?跟HTTP和HTTPS有什麼關系?

跟往常一樣,先說結論:

1

HTTP + SSL/TLS + TCP = HTTPS

TLS 是 SSL 新的别稱。舉個例子:

“TLS1.0”之于“SSL3.1”,猶“公元2015”之于“民國104”,或者是“一千克”之于“一公斤”,或者是“半斤”之于“八兩”:稱呼不同,但意思相同。

SSL 3.0版本之後的疊代版本被重新命名為TLS 1.0,也就是說:

1   TLS 1.0 = SSL 3.1

是以他們是一個東西,我們平常也經常簡單見到 “SSL/TLS” 這種說法。常用的是下面這些:

1  SSL 2.0

2  SSL 3.0

3  TLS 1.0 (SSL 3.1) 

4  TLS 1.1 (SSL 3.1)

5 TLS 1.2 (SSL 3.1)

那為什麼标題是“使用HTTPS”而沒有提及SSL和TLS什麼事? 要了解這個,要看下一個公式:

1

HTTP + SSL/TLS + TCP = HTTPS

打個比方:如果原來的 HTTP 是塑膠水管,容易被戳破;那麼如今新設計的 HTTPS 就像是在原有的塑膠水管之外,再包一層金屬水管。一來,原有的塑膠水管照樣運作;二來,用金屬加強了之後,不容易被戳破。

目前,應用最廣泛的是TLS 1.0,接下來是SSL 3.0。但是,主流浏覽器都已經實作了TLS 1.2的支援。Apple讓你的HTTP采用SSL/TLS協定,就是讓你從HTTP轉到HTTPS。

以前的HTTP不是也能用嗎?為什麼要用SSL/TLS,閑得慌?!Apple是不是又在反人類?

不使用SSL/TLS的HTTP通信,就是不加密的通信!

所有資訊明文傳播,帶來了三大風險:

竊聽風險(eavesdropping):第三方可以獲知通信内容。

篡改風險(tampering):第三方可以修改通信内容。

冒充風險(pretending):第三方可以冒充他人身份參與通信。

SSL/TLS協定是為了解決這三大風險而設計的,希望達到:

所有資訊都是加密傳播,第三方無法竊聽。

具有校驗機制,一旦被篡改,通信雙方會立刻發現。

配備身份證書,防止身份被冒充。

如何适配?---弱弱地問下:加班要多久?

正如文章開頭所說:

TLS 1.2 協定 強制增強資料通路安全 系統 Foundation 架構下的相關網絡請求,将不再預設使用 HTTP 等不安全的網絡協定,而預設采用 TLS 1.2。伺服器是以需要更新,以解析相關資料。如不更新,可通過在 Info.plist 中聲明,倒退回不安全的網絡請求。

方案一:立即讓公司的服務端更新使用TLS 1.2。

方案二:雖Apple不建議,但可通過在 Info.plist 中聲明,倒退回不安全的網絡請求依然能讓App通路指定http,甚至任意的http。

上面是比較嚴謹的做法,指定了能通路哪些特定的HTTP。當然也有暴力的做法: 徹底倒退回不安全的HTTP網絡請求,能任意進行HTTP請求,比如你在開發一款浏覽器App,或者你想偷懶,或者背景想偷懶,或者公司不給你更新伺服器。但目前Apple的官方文檔并未提及如何在 info.plist 配置可以參考本文:http://blog.6ag.cn/1065.html

二、更靈活的背景定位

如果不适配iOS9,就不能偷偷在背景定位。不過蘋果将允許出現這種場景:

同一App中的多個location manager,一些隻能在前台定位,另一些可在背景定位,并可随時開啟或者關閉特定location manager的背景定位。

如何偷偷在背景定位:

// 1. 執行個體化定位管理器

_locationManager = [[CLLocationManager alloc] init];

// 2. 設定代理

_locationManager.delegate = self;

// 3. 定位精度

[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

// 4.請求使用者權限:分為:?隻在前台開啟定位?在背景也可定位,

//注意:建議隻請求?和?中的一個,如果兩個權限都需要,隻請求?即可,

//??這樣的順序,将導緻bug:第一次啟動程式後,系統将隻請求?的權限,?的權限系統不會請求,隻會在下一次啟動應用時請求?

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {

//[_locationManager requestWhenInUseAuthorization];//?隻在前台開啟定位

[_locationManager requestAlwaysAuthorization];//?在背景也可定位

}

// 5.iOS9新特性:将允許出現這種場景:同一app中多個location manager:一些隻能在前台定位,另一些可在背景定位(并可随時禁止其背景定位)。

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {

_locationManager.allowsBackgroundLocationUpdates = YES;

}

// 6. 更新使用者位置

[_locationManager startUpdatingLocation];

但是如果照着這種方式嘗試,而沒有配置info.plist,100%你的程式會崩潰掉,并報錯:

*** Assertion failure in -[CLLocationManager setAllowsBackgroundLocationUpdates:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreLocationFramework_Sim/CoreLocation-1808.1.5/Framework/CoreLocation/CLLocationManager.m:593

要将 info.plist 配置如下:

iOS6、7、8、9新特性彙總和适配說明

對應的 Info.plist 的XML源碼是:

iOS6、7、8、9新特性彙總和适配說明

三、Bitcode

bitcode的了解應該是把程式編譯成的一種過渡代碼,然後蘋果再把這個過渡代碼編譯成可執行的程式。bitcode也允許蘋果在後期重新優化我們程式的二進制檔案,有類似于App瘦身的思想。未來Watch應用須包含Bitcode,iOS不強制,但Xcode7預設會開啟Bitcode。

用了xcode7的編譯器編譯之前沒問題的項目可能會出現下列報錯。

XXXX’ does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode forthistarget. forarchitecture arm64

問題的原因是:某些第三方庫還不支援bitcode。要不然是等待庫的開發者更新了此項功能我們更新庫,要不就是把這個bitcode禁用。禁用Bitcode,方法見下圖:

iOS6、7、8、9新特性彙總和适配說明

四、企業級分發

iOS9之前,企業級分發十分友善:點選App出現“信任按鈕”。

iOS9以後,企業級分發ipa包将遭到與Mac上dmg安裝包一樣的待遇。預設不能安裝,也不再出現“信任按鈕”,必須讓使用者進行gif圖中的設定。

iOS6、7、8、9新特性彙總和适配說明

五、URL scheme

URL scheme一般使用的場景是應用程式有分享或跳其他平台授權的功能,分享或授權後再跳回來。在iOS8并沒有做過多限制,在iOS9中,如果使用URL scheme必須在"info.plist"中将你要在外部調用的URL scheme列為白名單,否則不能使用。

canOpenURL: failed forURL : "mqzone://qqapp"- error: "This app is not allowed to query for scheme mqzone"

具體的解決方案也是要在info.plist中設定 LSApplicationQueriesSchemes 類型為數組,下面添加所有你用到的scheme

iOS6、7、8、9新特性彙總和适配說明

推薦一篇部落格: http://awkwardhare.com/post/121196006730/quick-take-on-ios-9-url-scheme-changes

其中最關鍵的是以下部分:

If you call the “canOpenURL” method on a URL that is not in your whitelist, it will return “NO”, even if there is an app installed that has registered to handle this scheme. A “This app is not allowed to query for scheme xxx” syslog entry will appear.

If you call the “openURL” method on a URL that is not in your whitelist, it will fail silently. A “This app is not allowed to query for scheme xxx” syslog entry will appear.

六、新字型

iOS8中,字型是Helvetica,中文的字型有點類似于“華文細黑”。隻是蘋果手機自帶渲染,是以看上去可能比普通的華文細黑要美觀。iOS9中,中文系統字型變為了專為中國設計的“蘋方” 有點類似于一種word字型“幼圓”。字型有輕微的加粗效果,并且最關鍵的是字型間隙變大了!

是以很多原本寫死了width的label可能會出現“...”的情況。

iOS6、7、8、9新特性彙總和适配說明
iOS6、7、8、9新特性彙總和适配說明

上面這兩張圖也可以直覺的看出同一個界面,同一個label的變化。

是以為了在界面顯示上不出錯,就算是固定長度的文字也還是建議使用sizetofit 或者ios向上取整 ceilf() 或者提前計算。

1  CGSize size = [title sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14.0f]}];

2  CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));

七、tableview

雖然現在的iOS9已經推送正式版了,但是iOS9使用時還是會感覺到App比以前更加卡頓了,tableView拖動時卡頓顯示的最為明顯。 并且之前遇到一個bug,原本好的項目用xcode7一編譯,tableView重新整理出了問題 ,[tableView reloadData]無效,有一行cell明明改變了但是重新整理不出來。 感覺可能是這個方法和某種新加的特性沖突了,猜測可能是reloadData的操作被推遲到下一個RunLoop執行最終失效。

解決的方法是,注釋[tableView reloadData],改用局部重新整理,問題居然就解決了。

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];

八、iPad适配Slide Over 和 Split View

iPad适配Slide Over 和 Split View,若想适配multi tasking特性,唯一的建議:

棄純代碼,改用storyboard、xib,縱觀蘋果WWDC所有Demo均是如此。

1 Mysteries of Auto Layout, Part 1

2 What's New in Storyboards

3 Implementing UI Designs in Interface Builder

4 Getting Started with Multitasking on iPad in iOS 9

5 Optimizing Your App for Multitasking on iPad in iOS

轉載于:https://www.cnblogs.com/jgCho/p/5163411.html