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

来源:http://www.cnblogs.com/jgCho/archive/2016/01/27/5163411.html
-Advertisement-
Play Games

一、關於記憶體警告ios6中廢除了viewDidUnload,viewWillUnload這兩個系統回調,收到記憶體警告時在didReceiveMemoryWarning中進行相關的處理。 二、關於屏幕旋轉同樣ios6 廢除了shouldAutorotateToInterfaceOrientation這


一、關於記憶體警告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新增了,設置陰影圖片的屬性。

1@property (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系統彈出以下警示欄:

五、[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取決於它顯示的位置。其他情況可以看下麵的圖例:

 

以下的代碼說明瞭使用一個既定的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;}

九、去掉了紋理顏色

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

十、UIButtonTypeRoundRect被UIButtonTypeSystem取代了4673_140117110855_1

在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中如何使用這個新功能: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。

十三、通過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/* 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;

十六、使用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以下是讓鍵盤可以在滾動的時候消失需要設置的屬性:

 

二十、使用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// 導入定位框架#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];

}

四、針對屏幕適配應運而生的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 配置如下:

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

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

 

四、企業級分發

iOS9之前,企業級分發十分方便:點擊App出現“信任按鈕”。

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

五、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.

六、新字體

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));

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 有些項目用xcode7打開運行,打包安裝到iOS9設備上程式會閃退。如果用xcode7以下編譯,然後打包到iOS9的設備上就是正常的。這是為什麼,關鍵是,怎麼解決? 答:iOS9發佈之後,有些app在新的系統下會經常出現閃退的情況,而官方也給了許多的適配與改變。以使用戶體驗更好。所以做為開發者怎樣為
  • 一、前言 android客戶端開發進入尾聲,負責SEO同事突然發給我一個涉及45個發佈渠道的噩耗,之前只發佈自有渠道的工作方式已經不滿足需求,所以引入最近比較流行的gradle打包技術。 gradle基於groovy語言,引入的原因也方便了以後從現在使用的eclipse開發環境遷移到Android
  • 昨天花了一下午的時間研究了下極光推送,也前也是沒做過,不知道從何下手!才開始的時候一看官方的SDK感覺好難,不過經過一系列的搗鼓之後,手機收到了推送信息,感覺其實並沒有那麼難! 1.配置開發證書(得有開發者賬號,個人,企業的都可以) 開發環境測試 在對 JPush iOS 開發環境進行測試前,請確保
  • 我們經常需要把一個數字轉成字元串,當你不需要配合其他字元串的時候可以用description. 1 /** 2 description屬於NSObject 3 值是NSNumber時候,不用stringWithFormate來轉化成字元串了.簡便得多 4 在解析/賦值的時候比較有用,當我們需要NSS
  • public class ButtonUtils { private static long lastClickTime; public synchronized static boolean isFastClick() { long time = System.currentTimeMillis(
  • 在上文,我們介紹了ios開發中的其中2種數據持久化方式:屬性列表、歸檔解檔。本節將繼續介紹另外2種iOS持久化數據的方法:資料庫 SQLite3、Core Data 的運用; 在本節,將通過對4個文本框內容的創建、修改,退出後臺,再重新回到後臺,來認識這兩種持久化數據的方式。效果圖如下【圖1】: 【
  • 前言 需要開發者在本地上使用openssl來生成私鑰和公鑰 由於mac 自帶openssl工具,所以不用像windows那樣要下載安裝openssl工具 步驟 1.創建一個文件夾,終端進入該文件夾 cd /Users/tanqihong/Desktop/rsa 2.終端輸入openssl打開工具 3
  • md5方法: 1.導入頭文件 #import <CommonCrypto/CommonDigest.h> 2.寫下麵的方法 - (NSString *)md5_32bit:(NSString *)input; 1).傳入的參數必須是字元串,NSData 可以轉成字元串. 2).得到的結果就是32個字
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...