iOS 8 新特性介紹
隨便去問任何人,他們都會告訴你WWDC2014是近年來最為激動的回憶。 整個大會沒有釋出任何新硬體,它是一次史無前例的軟體開發者盛宴!
僅是iOS 8和OS X Yosemite的釋出就能讓2014成為蘋果平臺劃時代的一年,加上Extension,Continuity,SpriteKit 改進,iOS SceneKit,Metal,HealthKit,Local Authentication和全新的照片框架。更不用說,Xcode和Interface Builder的明顯改觀,重新設計的iTunes Connect,TestFlight,崩潰報告和CloudKit。當然還有oh yeah-Swift。
更棒的是?蘋果放鬆了她的保密協定,也就是說我們可以現在就公開討論這些嶄新的玩具!
這周,我們將撥開iOS 8的雲霧,探討一些所有人都應該知道新API。
從現在開始NSHipster講主要使用Swift寫樣歷代嗎。夏天結束之前,我們希望能將全部的現存程式碼轉換為Swift,並且提供可以切換語言的選項。
NSProcessInfo -isOperatingSystemAtLeastVersion
忘記[[UIDevice currentDevice] systemVersion]和NSFoundationVersionNumber吧, 現在可以用NSProcessInfo -isOperatingSystemAtLeastVersion來確定系統版本。
import Foundation let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0) NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false
值得注意的是,在做相容性測試的時候還是應該使用SomeClass.class或respondsToSelector:。 Swift和C中的編譯器巨集可以用來根據不同生成配置和目標來選擇程式碼。
新的NSFormatter子類
Foundation中嚴重缺失的一項功能就是不能處理重量和長度單位轉換。在iOS 8和OS X Yosemite中,引進了三個新類NSEnergyFormatter,NSMassFormatter和NSLengthFormatter來彌補這一缺失。
這使得NSFormatter子類的數量翻了一倍, 之前只有NSNumberFormatter,NSDateFormatter和NSByteCountFormatter。
雖然這些都是Foundation的子類,但是它們主要都是在HealthKit當中使用。
NSEnergyFormatter
NSEnergyFormatter使用焦作為能量的原始單位,當處理健康資訊時,則使用卡.
let energyFormatter = NSEnergyFormatter() energyFormatter.forFoodEnergyUse = true let joules = 10_000.0 println(energyFormatter.stringFromJoules(joules)) // "2.39 Cal"
NSMassFormatter
雖然質量是物質存在的基本單位, 在HealthKit中,它主要指的是身體重量.
let massFormatter = NSMassFormatter() let kilograms = 60.0 println(massFormatter.stringFromKilograms(kilograms)) // "132 lb"
NSLengthFormatter
NSFormatter的最後一個新子類是NSLengthFormatter. 我們可以把它想象為MKDistanceFormatter的加強版。
let lengthFormatter = NSLengthFormatter() let meters = 5_000.0 println(lengthFormatter.stringFromMeters(meters)) // "3.107 mi"
CMPedometer
沿著iOS 8的健康路線, CMStepCounter被重新設計了. CMPedometer作為它的改良版本不僅可以即時獲取離散的點資料,並且可以同時跟蹤腳步和距離,甚至計算總共爬了多少級樓梯。
M7晶片真是功能強大.
import CoreMotion let lengthFormatter = NSLengthFormatter() let pedometer = CMPedometer() pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: { data, error in if !error { println("Steps Taken: \(data.numberOfSteps)") let distance = data.distance.doubleValue println("Distance: \)data.numberOfSteps)") let distance = data.distance.doubleValue println("Distance:lengthFormatter.stringFromMeters(distance))") let time = data.endDate.timeIntervalSinceDate(data.startDate) let speed = distance / time println("Speed: \(lengthFormatter.stringFromMeters(speed)) / s") } })
CMAltimeter
在支援的裝置上,CMAltimeter可以讓CMPedometer的floorsAscended,floorsDescended資料更加精準:
import CoreMotion let altimeter = CMAltimeter() if CMAltimeter.isRelativeAltitudeAvailable() { altimeter.startRelativeAltitudeUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { data, error in if !error { println("Relative Altitude: \(data.relativeAltitude)") } }) }
CLFloor
CLFloor的引入展示了蘋果進軍室內導航的巨集偉計劃,樓層資訊將扮演著重要的角色。
import CoreLocation class LocationManagerDelegate: NSObject, CLLocationManagerDelegate { func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) { let location: CLLocation? = locations[0] as? CLLocation if let floor: CLFloor? = location?.floor { println("Current Floor: $$floor?.level)") } } } let manager = CLLocationManager() manager.delegate = LocationManagerDelegate() manager.startUpdatingLocation()
HKStatistics
作為一個框架,HealthKit包含著大量的子類和常量。要想全部理解,HKStatistics是一個很好的開始。
HealthKit管理著所有的生理資訊,例如:心率,卡路里攝入量,血氧等等,並且通過統一的API聚合在一起。
下面這個例子演示瞭如何從一天的連續資料中,挖掘和獲取單獨的資料:
import HealthKit let collection: HKStatisticsCollection? = ... let statistics: HKStatistics? = collection!.statisticsForDate(NSDate()) for item: AnyObject in statistics!.sources { if let source = item as? HKSource { if let quantity: HKQuantity = statistics!.sumQuantityForSource(source) { if quantity.isCompatibleWithUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) { let massFormatter = NSMassFormatter() let kilograms = quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) println(massFormatter.stringFromKilograms(kilograms)) } if quantity.isCompatibleWithUnit(HKUnit.meterUnit()) { let lengthFormatter = NSLengthFormatter() let meters = quantity.doubleValueForUnit(HKUnit.meterUnit()) println(lengthFormatter.stringFromMeters(meters)) } if quantity.isCompatibleWithUnit(HKUnit.jouleUnit()) { let energyFormatter = NSEnergyFormatter() let joules = quantity.doubleValueForUnit(HKUnit.jouleUnit()) println(energyFormatter.stringFromJoules(joules)) } } } }
NSHipster將會在未來探討更多的HealthKit,敬請關注!
NSStream +getStreamsToHostWithName
在許多方面,WWDC 2014也是蘋果查漏補遺的一年,比如給NSStream新增了新的initializer(再也不用呼叫CFStreamCreatePairWithSocketToHost了),這就是:+[NSStream getStreamsToHostWithName:port:inputStream:outputStream:]
var inputStream: NSInputStream? var outputStream: NSOutputStream? NSStream.getStreamsToHostWithName(hostname: "nshipster.com", port: 5432, inputStream: &inputStream, outputStream: &outputStream)
NSString -localizedCaseInsensitiveContainsString
這又是一個NSString小而實用的修繕:
let string: NSString = "Café" let substring: NSString = "É" string.localizedCaseInsensitiveContainsString(substring) // true
CTRubyAnnotationRef
好吧,此Ruby非彼Ruby. . 這是用來給亞洲文字新增註音符號的.
@import CoreText; NSString *kanji = @"貓"; NSString *hiragana = @"ねこ"; CFStringRef furigana[kCTRubyPositionCount] = {(__bridge CFStringRef)hiragana, NULL, NULL, NULL}; CTRubyAnnotationRef ruby = CTRubyAnnotationCreate(kCTRubyAlignmentAuto, kCTRubyOverhangAuto, 0.5, furigana);
無可否認的是,文件中並沒有很清晰的描述具體如何將它整合進入你剩下的CoreText中,但是結果如下:
貓ねこ
新的日曆識別符
iOS 8和OS X中這些新的日曆識別符使得Fundation跟上了CLDR的步伐:
- NSCalendarIdentifierCoptic: 亞歷山大日曆, 科普特正教使用.
- NSCalendarIdentifierEthiopicAmeteMihret: 衣索比亞日曆, Amete Mihret
- NSCalendarIdentifierEthiopicAmeteAlem: 埃塞俄比日曆, Amete Alem
- NSCalendarIdentifierIslamicTabular: 一個簡單的伊斯蘭星曆.
- NSCalendarIdentifierIslamicUmmAlQura: 沙烏地阿拉伯伊斯蘭日曆.
NSURLCredentialStorage
自從去年NSURLSession的引入之後,Foundation的URL載入系統並沒有太大的改變。但是,新的NSURLCredentialStorage可以讓你更加方便地以移步,非閉包的方式獲取和儲存密碼。
import Foundation let session = NSURLSession() let task = session.dataTaskWithURL(NSURL(string: "http://nshipster.com"), completionHandler: { data, response, error in // ... }) let protectionSpace = NSURLProtectionSpace() NSURLCredentialStorage.getCredentialsForProtectionSpace(protectionSpace: protectionSpace, task: task, completionHandler: { credentials in // ... })
kUTTypeToDoItem
在比較過最新的API之後,你可能會注意到大量的新UTI常量。其中,kUTTypeToDoItem引起了我的注意:
import MobileCoreServices kUTTypeToDoItem // "public.to-do-item"
作為一個公共型別,iOS和OS X現在提供了統一的方式讓App之間共享任務。如果你碰巧正在開發一個任務管理工具,正確的整合好這個系統型別應該成為你的首要任務。
kCGImageMetadataShouldExcludeGPS
許多使用者完全不知道他們用手機拍攝的大部分照片都包含了GPS後設資料。更是有數不清的人因為這一個小細節洩露了自己的隱私。
最新的圖片I/O框架中加入了一個新的選項CGImageDestination:kCGImageMetadataShouldExcludeGPS讓你方便的控制是否包含GPS後設資料。
@import UIKit; @import ImageIO; @import MobileCoreServices; UIImage *image = ...; NSURL *fileURL = [NSURL fileURLWithPath:@"/path/to/output.jpg"]; NSString *UTI = kUTTypeJPEG; NSDictionary *options = @{ (__bridge id)kCGImageDestinationLossyCompressionQuality: @(0.75), (__bridge id)kCGImageMetadataShouldExcludeGPS: @(YES), }; CGImageDestinationRef imageDestinationRef = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, (__bridge CFStringRef)UTI, 1, NULL); CGImageDestinationAddImage(imageDestinationRef, [image CGImage], (__bridge CFDictionaryRef)options); CGImageDestinationFinalize(imageDestinationRef); CFRelease(imageDestinationRef);
WTF_PLATFORM_IOS
#define WTF_PLATFORM_IOS已經從JavaScriptCore中移除.
WKWebView
UIWebView已死. WKWebView萬歲.
WKWebView提供了Safari級別的效能,並且在UIWebView的基礎上提供了更多的配置選項:
import WebKit let preferences = WKPreferences() preferences.javaScriptCanOpenWindowsAutomatically = false let configuration = WKWebViewConfiguration() configuration.preferences = preferences let webView = WKWebView(frame: self.view.bounds, configuration: configuration) let request = NSURLRequest(URL: NSURL(string: "http://nshipster.com")) webView.loadRequest(request)
NSQualityOfService
執行緒這個概念已經在蘋果的框架中被系統性的忽略。這對於開發者而言是件好事。
沿著這個趨勢,NSOperation中新的qualityOfService的屬性取代了原來的threadPriority。通過它可以推遲那些不重要的任務,從而讓使用者體驗更加流暢。
NSQualityOfService列舉定義了以下值:
- UserInteractive:和圖形處理相關的任務,比如滾動和動畫。
- UserInitiated:使用者請求的任務,但是不需要精確到毫秒級。例如,如果使用者請求開啟電子郵件App來檢視郵件。
- Utility:週期性的使用者請求任務。比如,電子郵件App可能被設定成每五分鐘自動檢查新郵件。但是在系統資源極度匱乏的時候,將這個週期性的任務推遲幾分鐘也沒有大礙。
- Background:後臺任務,使用者可能並不會察覺對這些任務。比如,電子郵件App對郵件進行引索以方便搜尋。
Quality of Service將在iOS 8和OS X Yosemite中廣泛的應用,所以留意所有能利用它們的機會。
LocalAuthentication
最後,最令人期待的iOS 8新功能之一:LocalAuthentication。自從iPhone 5S加入TouchID,開發者就對它的應用前景垂涎三尺。
想象一下,只要有CloudKit和LocalAuthentication,建立新賬號的煩惱講不復存在。只需要掃描一下你的手就搞定了!
LocalAuthentication以LAContext的方式工作,驗證宣告的規格,然後返回是否驗證成功。整個過程中,使用者的生物資訊都被安全的儲存在硬體當中。
LAContext *context = [[LAContext alloc] init]; NSError *error = nil; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) { [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:NSLocalizedString(@"...", nil) reply:^(BOOL success, NSError *error) { if (success) { // ... } else { NSLog(@"%@", error); } }]; } else { NSLog(@"%@", error); }
雖然這些天每個人都在討論Swift,但是作為一個開發者你更應該關注的是這些iOS 8和OS X Yosemite的新API。它們可以讓你實實在在的_做_一些事。
如果你想接著探索,dive into the iOS 7.1 to 8.0 API diffs可以讓你領會這些變化的重要性。當然,4000多的新API,很多隻是細微的改變或者將方法改為屬性,但是,它們值得擁有!
相關文章
- Angular 8的新特性介紹Angular
- TiDB 5.0.0新特性介紹TiDB
- iOS 8 之後UINavigationController新特性iOSUINavigationController
- 【IDL】IDL 8.4新特性介紹
- AnalyticDB for PostgreSQL 6.0 新特性介紹SQL
- Apache Cassandra 4.0新特性介紹Apache
- JavaScript 6 的新特性介紹JavaScript
- [譯] Chrome 71 新特性介紹Chrome
- webpack4新特性介紹Web
- React v16.6 新特性介紹React
- Redis4.0的新特性介紹Redis
- K8s的介紹和特性K8S
- 玩轉iOS開發:iOS 8 新特性《Share Extension》iOS
- Dash 2.16版本新特性介紹
- Dash 2.17版本新特性介紹
- SQL?Server新特性SequenceNumber用法介紹YTZBSQLServer
- ECMAScript 2017(ES8)新特性簡介
- Flutter 3.7 新特性:介紹後臺isolate通道Flutter
- MyRocksTTL特性介紹
- 玩轉iOS開發:iOS 11 新特性《Layout的新特性》iOS
- Jetbrains CLion特性介紹AI
- Jetbrains pycharm特性介紹AIPyCharm
- Jetbrains datagrip特性介紹AI
- Jetbrains goland特性介紹AIGoLand
- ECMAScript6.0新特性介紹第七篇
- Java 8 新特性Java
- Java 8 新特性Java
- Kyma Application Connectivity 特性介紹APP
- Zookeeper 節點特性介紹
- MySQL 8.0 新增特性介紹MySql
- (8)ILA介紹
- 【劉文彬】 EOS1.1版本新特性介紹
- 【iOS印象】Swift 4.1 新特性iOSSwift
- Java 8 新特性 StreamJava
- php8新特性PHP
- JAVA8新特性Java
- JDK8新特性JDK
- Java8 新特性Java
- Docker的原理及特性介紹Docker