iOS六、七、八、9新特性彙總和適配說明

1、關於內存警告ios6中廢除了viewDidUnload,viewWillUnload這兩個系統回調,收到內存警告時在didReceiveMemoryWarning中進行相關的處理。html

2、關於屏幕旋轉一樣ios6 廢除了shouldAutorotateToInterfaceOrientation這個旋轉屏幕的設置接口。必須在兩個新接口中設置旋轉屬性:shouldAutorotate、supportedInterfaceOrientations。收到旋轉事件後的處理,一樣在willRotateToInterfaceOrientation和didRotateFromInterfaceOrientation中進行。ios

3、UISwitchios6下,新增瞭如下幾個屬性,能夠設置開關的顏色以及背景圖。@property (nonatomic,  retain) UIColor *tintColor;web

 @property (nonatomic,  retain) UIColor *thumbTintColor; 數組

@property (nonatomic,  retain) UIImage *onImage; xcode

@property (nonatomic,  retain) UIImage *offImage;瀏覽器

4、UINavigationBarios6新增了,設置陰影圖片的屬性。安全

1@property (nonatomic, retain) UIImage *shadowImage;服務器

5、UIImage能夠在ios6下設置圖片的scale比例尺寸了。網絡

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

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

6、UIRefreshControl以前蘋果官方是沒有現成的下拉刷新的控件,都是本身實現或者使用比較成熟的開源庫。ios6蘋果加入了UIRefreshControl,配合UITableView直接實現下拉刷新。

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

iOS7新特性

1、已禁用-[UIDevice uniqueIdentifier]蘋果老是把用戶的隱私看的很重要。

-[UIDevice uniqueIdentifier]在iOS5實際在iOS5的時候已經被遺棄了,可是iOS7中已經徹底的禁用了它。Xcode5甚至不會容許你編譯包含了指引到-[UIDevice uniqueIdentifier]的app。此外,iOS7以前的使用了-[UIDevice uniqueIdentifier] 的app若是在iOS7上運行,它不會返回設備的UUID,而是會返回一串字符串,以FFFFFFFF開頭,跟着-[UIDevice identifierForVendor]的十六進制值。

2、UIPasteboard由共享變爲沙盒化了UIPasteboard過去是用來作app之間的數據分享的。UIPasteboard本無問題,可是開發者開始使用它來存儲標識符,和其餘的相關app分享這些標識符的時候問題就出現了。有一個使用這種把戲的就是OpenUDID。在iOS7中,使用

+[UIPasteboard pasteboardWithName:create:]和 

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

3、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會返回給在這個設備上全部軟件供應商相同的 一個值,因此只能在廣告的時候使用。這個值會由於不少狀況而有所變化,好比說用戶初始化設備的時候便會改變。

4、iOS如今要求app如需使用麥克風,須要徵得用戶贊成之前若是app須要使用用戶的位置,通信錄,日曆,提醒以及照片,接受推送消息,使用用戶的社交網絡的時候須要徵得用戶的贊成。如今在iOS7當中,使用麥克風也須要取得用戶贊成了。若是用戶不容許app使用麥克風的話,那麼須要使用麥克風的app就不能接收不到任何聲音。如下的代碼是用來查詢用戶是否容許app使用麥克風

//第一次調用這個方法的時候,系統會提示用戶讓他贊成你的app獲取麥克風的數據/

/ 其餘時候調用方法的時候,則不會提醒用戶// 而會傳遞以前的值來要求用戶贊成[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted)

 {    if (granted) {        

// 用戶贊成獲取數據    } else {       

 // 能夠顯示一個提示框告訴用戶這個app沒有獲得容許?    }}];你同時還要注意,若是你在得到用戶的贊成以前使用任何方法來使用麥克風的話,會引發iOS系統彈出如下警示欄:

5、[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,若是有的話看看它是不是必須的,不是必須的話就把它所有移除。

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

7、設置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取決於它顯示的位置。其餘狀況能夠看下面的圖例:

 

如下的代碼說明了使用一個既定的rendering模式建立圖片是多麼簡單:123UIImage *img = [UIImage imageNamed:@"myimage"]; img = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];8、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;}

9、去掉了紋理顏色

紋理顏色?對,再也不使用他們了,不能再建立能夠展示紋理的顏色。根據UIInterface.h文件中的註釋,-[UIColor groupTableViewBackgroundColor]應該是要在iOS6當中即被刪除了,可是它僅僅只是不像以前那樣返回紋理顏色了。然而,如下的顏色在iOS7當中被刪除了:12345+ (UIColor *)viewFlipsideBackgroundColor; + (UIColor *)scrollViewTexturedBackgroundColor; + (UIColor *)underPageBackgroundColor;

10、UIButtonTypeRoundRect被UIButtonTypeSystem取代了4673_140117110855_1

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

11、檢查無線路由是否可用定製一個視頻播放器的能力在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;


12、瞭解蜂窩網絡在iOS7以前,是使用Reachability來檢測設備是否鏈接到WWAN或是Wifi的。iOS7在這個基礎上更進了一步,它會告訴你的設備鏈接上的是那種蜂窩網絡,好比說是Edge網絡,HSDPA網絡,或是LTE網絡。告訴用戶他們鏈接上的是哪一種網絡能夠優化用戶體驗,由於這樣他們會知道網速如何,不會去請求須要高網速的網絡請求。這是CTTelephonyNetworkInfo的部分功能,它是CoreTelephony框架的一部分。iOS7還增長了currentRadioAccessTechnology屬性和CTRadioAccessTechnologyDidChangeNotification到這個類。還有一些新的字符串常量來定義可能的值,好比說是CTRadioAccessTechnologyLTE。如下代碼告訴你在app delegate中如何使用這個新功能:123456789101112131415161718192021222324@import CoreTelephony.CTTelephonyNetworkInfo; // new modules syntax!@interface AppDelegate ()// we need to keep a reference to the CTTelephonyNetworkInfo object, otherwise the notifications won't be fired!@property (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。

十3、經過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的好方法。

十4、使用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了。

十5、使用原生的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/* These methods first appeared in NSData.h on OS X 10.9 and iOS 7.0. They are deprecated in the same releases in favor of the methods in theNSDataBase64Encodingcategory. However, these methods have existed for several releases, so they may be used for applications targeting releases prior to OS X 10.9 and iOS 7.0. */- (id)initWithBase64Encoding:(NSString *)base64String;- (NSString *)base64Encoding;

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

。然而,iOS7提供一個嶄新的推送方法:UIApplicationUserDidTakeScreenshotNotification。只要像往常同樣訂閱便可知道何時截圖了。注意:UIApplicationUserDidTakeScreenshotNotification 將會在截圖完成以後顯示。如今在截圖截取以前沒法獲得通知。但願蘋果會在iOS8當中增長UIApplicationUserWillTakeScreenshotNotification。

十7、實現多語言語音合成若是可讓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];

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

十9、使用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如下是讓鍵盤能夠在滾動的時候消失須要設置的屬性:

 

二10、使用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!");    

}}

二11、給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新特性1、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];

2、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];

3、獲取用戶受權的用戶隱私保護地圖定位示例 :1234567891011121314151617181920212223242526// 導入定位框架#import@interface 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];

}

4、針對屏幕適配應運而生的size classes

size classes是爲了解決storyboard只能訂製一種屏幕樣式的問題,它再也不是具體的尺寸,而是抽象尺寸經過寬/高 的compact、any、regular 組成了九種組合包含了全部蘋果設備的尺寸。

iOS9新特性

1、網絡適配

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

2、更靈活的後臺定位

若是不適配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 配置以下:

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

3、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,方法見下圖:

 

4、企業級分發

iOS9以前,企業級分發十分方便:點擊App出現「信任按鈕」。

iOS9之後,企業級分發ipa包將遭到與Mac上dmg安裝包同樣的待遇。默認不能安裝,也再也不出現「信任按鈕」,必須讓用戶進行gif圖中的設置。

5、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

 

推薦一篇博客: 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.

6、新字體

iOS8中,字體是Helvetica,中文的字體有點相似於「華文細黑」。只是蘋果手機自帶渲染,因此看上去可能比普通的華文細黑要美觀。iOS9中,中文系統字體變爲了專爲中國設計的「蘋方」 有點相似於一種word字體「幼圓」。字體有輕微的加粗效果,而且最關鍵的是字體間隙變大了!

因此不少本來寫死了width的label可能會出現「...」的狀況。

上面這兩張圖也能夠直觀的看出同一個界面,同一個label的變化。

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

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

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

7、tableview

雖然如今的iOS9已經推送正式版了,可是iOS9使用時仍是會感受到App比之前更加卡頓了,tableView拖動時卡頓顯示的最爲明顯。 而且以前遇到一個bug,本來好的項目用xcode7一編譯,tableView刷新出了問題 ,[tableView reloadData]無效,有一行cell明明改變了可是刷新不出來。 感受多是這個方法和某種新加的特性衝突了,猜想多是reloadData的操做被推遲到下一個RunLoop執行最終失效。

解決的方法是,註釋[tableView reloadData],改用局部刷新,問題竟然就解決了。

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

8、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

相關文章
相關標籤/搜索