iOS 8 新特性介紹
隨便去問任何人,他們都會告訴你WWDC2014是近年來最為激動的回憶。 整個大會沒有發(fā)布任何新硬件,它是一次史無前例的軟件開發(fā)者盛宴!
僅是iOS 8和OS X Yosemite的發(fā)布就能讓2014成為蘋果平臺劃時代的一年,加上Extension,Continuity,SpriteKit 改進(jìn),iOS SceneKit,Metal,HealthKit,Local Authentication和全新的照片框架。更不用說,Xcode和Interface Builder的明顯改觀,重新設(shè)計(jì)的iTunes Connect,TestFlight,崩潰報(bào)告和CloudKit。當(dāng)然還有oh yeah-Swift。
更棒的是?蘋果放松了她的保密協(xié)定,也就是說我們可以現(xiàn)在就公開討論這些嶄新的玩具!
這周,我們將撥開iOS 8的云霧,探討一些所有人都應(yīng)該知道新API。
從現(xiàn)在開始NSHipster講主要使用Swift寫樣歷代嗎。夏天結(jié)束之前,我們希望能將全部的現(xiàn)存代碼轉(zhuǎn)換為Swift,并且提供可以切換語言的選項(xiàng)。
NSProcessInfo -isOperatingSystemAtLeastVersion忘記[[UIDevice currentDevice] systemVersion]和NSFoundationVersionNumber吧, 現(xiàn)在可以用NSProcessInfo -isOperatingSystemAtLeastVersion來確定系統(tǒng)版本。
import Foundationlet yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false
值得注意的是,在做兼容性測試的時候還是應(yīng)該使用SomeClass.class或respondsToSelector:。 Swift和C中的編譯器宏可以用來根據(jù)不同生成配置和目標(biāo)來選擇代碼。
新的NSFormatter子類Foundation中嚴(yán)重缺失的一項(xiàng)功能就是不能處理重量和長度單位轉(zhuǎn)換。在iOS 8和OS X Yosemite中,引進(jìn)了三個新類NSEnergyFormatter,NSMassFormatter和NSLengthFormatter來彌補(bǔ)這一缺失。
這使得NSFormatter子類的數(shù)量翻了一倍, 之前只有NSNumberFormatter,NSDateFormatter和NSByteCountFormatter。
雖然這些都是Foundation的子類,但是它們主要都是在HealthKit當(dāng)中使用。
NSEnergyFormatterNSEnergyFormatter使用焦作為能量的原始單位,當(dāng)處理健康信息時,則使用卡.
let energyFormatter = NSEnergyFormatter()energyFormatter.forFoodEnergyUse = truelet joules = 10_000.0println(energyFormatter.stringFromJoules(joules)) // "2.39 Cal"NSMassFormatter
雖然質(zhì)量是物質(zhì)存在的基本單位, 在HealthKit中,它主要指的是身體重量.
let massFormatter = NSMassFormatter()let kilograms = 60.0println(massFormatter.stringFromKilograms(kilograms)) // "132 lb"NSLengthFormatter
NSFormatter的最后一個新子類是NSLengthFormatter. 我們可以把它想象為MKDistanceFormatter的加強(qiáng)版。
let lengthFormatter = NSLengthFormatter()let meters = 5_000.0println(lengthFormatter.stringFromMeters(meters)) // "3.107 mi" CMPedometer
沿著iOS 8的健康路線, CMStepCounter被重新設(shè)計(jì)了. CMPedometer作為它的改良版本不僅可以即時獲取離散的點(diǎn)數(shù)據(jù),并且可以同時跟蹤腳步和距離,甚至計(jì)算總共爬了多少級樓梯。
M7芯片真是功能強(qiáng)大.
import CoreMotionlet lengthFormatter = NSLengthFormatter()let pedometer = CMPedometer()pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: { data, error in if !error {println("Steps Taken: (data.numberOfSteps)")let distance = data.distance.doubleValueprintln("Distance: )data.numberOfSteps)')let distance = data.distance.doubleValueprintln('Distance: lengthFormatter.stringFromMeters(distance))")let time = data.endDate.timeIntervalSinceDate(data.startDate)let speed = distance / timeprintln("Speed: (lengthFormatter.stringFromMeters(speed)) / s") }}) CMAltimeter
在支持的設(shè)備上,CMAltimeter可以讓CMPedometer的floorsAscended,floorsDescended數(shù)據(jù)更加精準(zhǔn):
import CoreMotionlet altimeter = CMAltimeter()if CMAltimeter.isRelativeAltitudeAvailable() { altimeter.startRelativeAltitudeUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { data, error inif !error { println("Relative Altitude: (data.relativeAltitude)")} })} CLFloor
CLFloor的引入展示了蘋果進(jìn)軍室內(nèi)導(dǎo)航的宏偉計(jì)劃,樓層信息將扮演著重要的角色。
import CoreLocationclass LocationManagerDelegate: NSObject, CLLocationManagerDelegate { func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {let location: CLLocation? = locations[0] as? CLLocationif let floor: CLFloor? = location?.floor { println("Current Floor: $$floor?.level)")} }}let manager = CLLocationManager()manager.delegate = LocationManagerDelegate()manager.startUpdatingLocation() HKStatistics
作為一個框架,HealthKit包含著大量的子類和常量。要想全部理解,HKStatistics是一個很好的開始。
HealthKit管理著所有的生理信息,例如:心率,卡路里攝入量,血氧等等,并且通過統(tǒng)一的API聚合在一起。
下面這個例子演示了如何從一天的連續(xù)數(shù)據(jù)中,挖掘和獲取單獨(dú)的數(shù)據(jù):
import HealthKitlet 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,敬請關(guān)注!
NSStream +getStreamsToHostWithName在許多方面,WWDC 2014也是蘋果查漏補(bǔ)遺的一年,比如給NSStream添加了新的initializer(再也不用調(diào)用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小而實(shí)用的修繕:
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);
無可否認(rèn)的是,文檔中并沒有很清晰的描述具體如何將它整合進(jìn)入你剩下的CoreText中,但是結(jié)果如下:
貓ねこ
新的日歷識別符iOS 8和OS X中這些新的日歷識別符使得Fundation跟上了CLDR的步伐:
NSCalendarIdentifierCoptic: 亞歷山大日歷, 科普特正教使用.NSCalendarIdentifierEthiopicAmeteMihret: 埃塞俄比亞日歷, Amete MihretNSCalendarIdentifierEthiopicAmeteAlem: 埃塞俄比日歷, Amete AlemNSCalendarIdentifierIslamicTabular: 一個簡單的伊斯蘭星歷.NSCalendarIdentifierIslamicUmmAlQura: 沙特阿拉伯伊斯蘭日歷. NSURLCredentialStorage自從去年NSURLSession的引入之后,F(xiàn)oundation的URL載入系統(tǒng)并沒有太大的改變。但是,新的NSURLCredentialStorage可以讓你更加方便地以移步,非閉包的方式獲取和存儲密碼。
import Foundationlet 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 MobileCoreServiceskUTTypeToDoItem // "public.to-do-item"
作為一個公共類型,iOS和OS X現(xiàn)在提供了統(tǒng)一的方式讓App之間共享任務(wù)。如果你碰巧正在開發(fā)一個任務(wù)管理工具,正確的整合好這個系統(tǒng)類型應(yīng)該成為你的首要任務(wù)。
kCGImageMetadataShouldExcludeGPS許多用戶完全不知道他們用手機(jī)拍攝的大部分照片都包含了GPS元數(shù)據(jù)。更是有數(shù)不清的人因?yàn)檫@一個小細(xì)節(jié)泄露了自己的隱私。
最新的圖片I/O框架中加入了一個新的選項(xiàng)CGImageDestination:kCGImageMetadataShouldExcludeGPS讓你方便的控制是否包含GPS元數(shù)據(jù)。
@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已經(jīng)從JavaScriptCore中移除.
WKWebViewUIWebView已死. WKWebView萬歲.
WKWebView提供了Safari級別的性能,并且在UIWebView的基礎(chǔ)上提供了更多的配置選項(xiàng):
import WebKitlet preferences = WKPreferences()preferences.javaScriptCanOpenWindowsAutomatically = falselet configuration = WKWebViewConfiguration()configuration.preferences = preferenceslet webView = WKWebView(frame: self.view.bounds, configuration: configuration)let request = NSURLRequest(URL: NSURL(string: "http://nshipster.com"))webView.loadRequest(request) NSQualityOfService
線程這個概念已經(jīng)在蘋果的框架中被系統(tǒng)性的忽略。這對于開發(fā)者而言是件好事。
沿著這個趨勢,NSOperation中新的qualityOfService的屬性取代了原來的threadPriority。通過它可以推遲那些不重要的任務(wù),從而讓用戶體驗(yàn)更加流暢。
NSQualityOfService枚舉定義了以下值:
UserInteractive:和圖形處理相關(guān)的任務(wù),比如滾動和動畫。UserInitiated:用戶請求的任務(wù),但是不需要精確到毫秒級。例如,如果用戶請求打開電子郵件App來查看郵件。Utility:周期性的用戶請求任務(wù)。比如,電子郵件App可能被設(shè)置成每五分鐘自動檢查新郵件。但是在系統(tǒng)資源極度匱乏的時候,將這個周期性的任務(wù)推遲幾分鐘也沒有大礙。Background:后臺任務(wù),用戶可能并不會察覺對這些任務(wù)。比如,電子郵件App對郵件進(jìn)行引索以方便搜索。Quality of Service將在iOS 8和OS X Yosemite中廣泛的應(yīng)用,所以留意所有能利用它們的機(jī)會。
LocalAuthentication最后,最令人期待的iOS 8新功能之一:LocalAuthentication。自從iPhone 5S加入TouchID,開發(fā)者就對它的應(yīng)用前景垂涎三尺。
想象一下,只要有CloudKit和LocalAuthentication,創(chuàng)建新賬號的煩惱講不復(fù)存在。只需要掃描一下你的手就搞定了!
LocalAuthentication以LAContext的方式工作,驗(yàn)證聲明的規(guī)格,然后返回是否驗(yàn)證成功。整個過程中,用戶的生物信息都被安全的儲存在硬件當(dāng)中。
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,但是作為一個開發(fā)者你更應(yīng)該關(guān)注的是這些iOS 8和OS X Yosemite的新API。它們可以讓你實(shí)實(shí)在在的_做_一些事。
如果你想接著探索,dive into the iOS 7.1 to 8.0 API diffs可以讓你領(lǐng)會這些變化的重要性。當(dāng)然,4000多的新API,很多只是細(xì)微的改變或者將方法改為屬性,但是,它們值得擁有!
相關(guān)文章:
1. PHP循環(huán)與分支知識點(diǎn)梳理2. ASP基礎(chǔ)入門第三篇(ASP腳本基礎(chǔ))3. 解析原生JS getComputedStyle4. 無線標(biāo)記語言(WML)基礎(chǔ)之WMLScript 基礎(chǔ)第1/2頁5. ASP刪除img標(biāo)簽的style屬性只保留src的正則函數(shù)6. ASP實(shí)現(xiàn)加法驗(yàn)證碼7. 讀大數(shù)據(jù)量的XML文件的讀取問題8. css代碼優(yōu)化的12個技巧9. 利用CSS3新特性創(chuàng)建透明邊框三角10. 前端從瀏覽器的渲染到性能優(yōu)化
