标签:
来源:nshipster.cn 发布时间:2014-07-06 阅读次数:2152
随便去问任何人,他们都会告诉你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,并且提供可以切换语言的选项。
忘记[[UIDevice currentDevice] systemVersion]和NSFoundationVersionNumber吧, 现在可以用NSProcessInfo -isOperatingSystemAtLeastVersion来确定系统版本。
1
2
3
4
|
import Foundation let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0) NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false |
值得注意的是,在做兼容性测试的时候还是应该使用SomeClass.class或respondsToSelector:。 Swift和C中的编译器宏可以用来根据不同生成配置和目标来选择代码。
Foundation中严重缺失的一项功能就是不能处理重量和长度单位转换。在iOS 8和OS X Yosemite中,引进了三个新类NSEnergyFormatter,NSMassFormatter和NSLengthFormatter来弥补这一缺失。
这使得NSFormatter子类的数量翻了一倍, 之前只有NSNumberFormatter,NSDateFormatter和NSByteCountFormatter。
虽然这些都是Foundation的子类,但是它们主要都是在HealthKit当中使用。
NSEnergyFormatter使用焦作为能量的原始单位,当处理健康信息时,则使用卡.
1
2
3
4
5
|
let energyFormatter = NSEnergyFormatter() energyFormatter.forFoodEnergyUse = true let joules = 10_000.0 println(energyFormatter.stringFromJoules(joules)) // "2.39 Cal" |
虽然质量是物质存在的基本单位, 在HealthKit中,它主要指的是身体重量.
1
2
3
|
let massFormatter = NSMassFormatter() let kilograms = 60.0 println(massFormatter.stringFromKilograms(kilograms)) // "132 lb" |
NSFormatter的最后一个新子类是NSLengthFormatter. 我们可以把它想象为MKDistanceFormatter的加强版。
1
2
3
|
let lengthFormatter = NSLengthFormatter() let meters = 5_000.0 println(lengthFormatter.stringFromMeters(meters)) // "3.107 mi" |
沿着iOS 8的健康路线, CMStepCounter被重新设计了. CMPedometer作为它的改良版本不仅可以即时获取离散的点数据,并且可以同时跟踪脚步和距离,甚至计算总共爬了多少级楼梯。
M7芯片真是功能强大.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import CoreMotion let lengthFormatter = NSLengthFormatter() let pedometer = CMPedometer() pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: { <span id= "9_nwp" style= "width: auto; height: auto; float: none;" ><a id= "9_nwl" href= "http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=47&ch=0&di=128&fv=20&is_app=0&jk=6ffe5dec0d9071f6&k=data&k0=data&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=f671900dec5dfe6f&ssp2=1&stid=0&t=tpclicked3_hc&td=1922429&tu=u1922429&u=http%3A%2F%2Fwww%2Eadmin10000%2Ecom%2Fdocument%2F4675%2Ehtml&urlid=0" target= "_blank" mpid= "9" style= "text-decoration: none;" ><span style= "color:#0000ff;font-size:14px;width:auto;height:auto;float:none;" >data</span></a></span>, error in if !error { println( "Steps Taken: <span class=" MathJax_Preview ">\(<span id=" 0_nwp " style=" width: auto; height: auto; float : none; "><a id=" 0_nwl " href=" http: //cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=47&ch=0&di=128&fv=20&is_app=0&jk=6ffe5dec0d9071f6&k=data&k0=data&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=f671900dec5dfe6f&ssp2=1&stid=0&t=tpclicked3_hc&td=1922429&tu=u1922429&u=http%3A%2F%2Fwww%2Eadmin10000%2Ecom%2Fdocument%2F4675%2Ehtml&urlid=0" target="_blank" mpid="0" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">data</span></a></span>.numberOfSteps)") let distance = data.distance.doubleValue println( "Distance: \)</span><script type=" math/tex ">data.numberOfSteps)" ) let distance = data.distance.doubleValue println( "Distance: </script>lengthFormatter.stringFromMeters(distance))" ) let time = data.endDate.timeIntervalSinceDate(data.startDate) let speed = distance / time println( "Speed: <span class=" MathJax_Preview ">\(lengthFormatter.stringFromMeters(speed)) / s" ) } })</span> |
在支持的设备上,CMAltimeter可以让CMPedometer的floorsAscended,floorsDescended数据更加精准:
1
2
3
4
5
6
7
8
9
10
|
import CoreMotion let altimeter = CMAltimeter() if CMAltimeter.isRelativeAltitudeAvailable() { altimeter.startRelativeAltitudeUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { <span id= "8_nwp" style= "width: auto; height: auto; float: none;" ><a id= "8_nwl" href= "http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=47&ch=0&di=128&fv=20&is_app=0&jk=6ffe5dec0d9071f6&k=data&k0=data&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=f671900dec5dfe6f&ssp2=1&stid=0&t=tpclicked3_hc&td=1922429&tu=u1922429&u=http%3A%2F%2Fwww%2Eadmin10000%2Ecom%2Fdocument%2F4675%2Ehtml&urlid=0" target= "_blank" mpid= "8" style= "text-decoration: none;" ><span style= "color:#0000ff;font-size:14px;width:auto;height:auto;float:none;" >data</span></a></span>, error in if !error { println( "Relative Altitude: \(data.relativeAltitude)" ) } }) } |
CLFloor的引入展示了苹果进军室内导航的宏伟计划,楼层信息将扮演着重要的角色。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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() |
作为一个框架,HealthKit包含着大量的子类和常量。要想全部理解,HKStatistics是一个很好的开始。
HealthKit管理着所有的生理信息,例如:心率,卡路里摄入量,血氧等等,并且通过统一的API聚合在一起。
下面这个例子演示了如何从一天的连续数据中,挖掘和获取单独的数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
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,敬请关注!
在许多方面,WWDC 2014也是苹果查漏补遗的一年,比如给NSStream添加了新的initializer(再也不用调用CFStreamCreatePairWithSocketToHost了),这就是:+[NSStream getStreamsToHostWithName:port:inputStream:outputStream:]
1
2
3
4
5
6
7
|
var inputStream: NSInputStream? var outputStream: NSOutputStream? NSStream.getStreamsToHostWithName(hostname: "nshipster.com" , port: 5432, inputStream: &inputStream, outputStream: &outputStream) |
这又是一个NSString小而实用的修缮:
1
2
3
4
|
let string : NSString = "Café" let substring: NSString = "É" string .localizedCaseInsensitiveContainsString(substring) // true |
好吧,此Ruby非彼Ruby. . 这是用来给亚洲文字添加注音符号的.
1
2
3
4
5
6
7
8
9
10
|
@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的步伐:
自从去年NSURLSession的引入之后,Foundation的URL载入系统并没有太大的改变。但是,新的NSURLCredentialStorage可以让你更加方便地以移步,非闭包的方式获取和存储密码。
1
2
3
4
5
6
7
8
9
10
11
|
import Foundation let session = NSURLSession() let task = session.<span id= "4_nwp" style= "width: auto; height: auto; float: none;" ><a id= "4_nwl" href= "http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=47&ch=0&di=128&fv=20&is_app=0&jk=6ffe5dec0d9071f6&k=data&k0=data&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=f671900dec5dfe6f&ssp2=1&stid=0&t=tpclicked3_hc&td=1922429&tu=u1922429&u=http%3A%2F%2Fwww%2Eadmin10000%2Ecom%2Fdocument%2F4675%2Ehtml&urlid=0" target= "_blank" mpid= "4" style= "text-decoration: none;" ><span style= "color:#0000ff;font-size:14px;width:auto;height:auto;float:none;" >data</span></a></span>TaskWithURL(NSURL( string : "http://nshipster.com" ), completionHandler: { data, response, error in // ... }) let protectionSpace = NSURLProtectionSpace() NSURLCredentialStorage.getCredentialsForProtectionSpace(protectionSpace: protectionSpace, task: task, completionHandler: { credentials in // ... }) |
在比较过最新的API之后,你可能会注意到大量的新UTI常量。其中,kUTTypeToDoItem引起了我的注意:
1
2
3
|
import MobileCoreServices kUTTypeToDoItem // "public.to-do-item" |
作为一个公共类型,iOS和OS X现在提供了统一的方式让App之间共享任务。如果你碰巧正在开发一个任务管理工具,正确的整合好这个系统类型应该成为你的首要任务。
许多用户完全不知道他们用手机拍摄的大部分照片都包含了GPS元数据。更是有数不清的人因为这一个小细节泄露了自己的隐私。
最新的图片I/O框架中加入了一个新的选项CGImageDestination:kCGImageMetadataShouldExcludeGPS让你方便的控制是否包含GPS元数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@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); |
#define WTF_PLATFORM_IOS已经从JavaScriptCore中移除.
UIWebView已死. WKWebView万岁.
WKWebView提供了Safari级别的性能,并且在UIWebView的基础上提供了更多的配置选项:
1
2
3
4
5
6
7
8
9
10
11
|
import WebKit let preferences = WKPreferences() preferences.javaScriptCanOpenWindowsAutomatically = false let configuration = WKWebViewConfiguration() configuration.preferences = preferences let webView = WKWebView(frame: self.view.bounds, configuration: configuration) webView.loadRequest(request) |
线程这个概念已经在苹果的框架中被系统性的忽略。这对于开发者而言是件好事。
沿着这个趋势,NSOperation中新的qualityOfService的属性取代了原来的threadPriority。通过它可以推迟那些不重要的任务,从而让用户体验更加流畅。
NSQualityOfService枚举定义了以下值:
Quality of Service将在iOS 8和OS X Yosemite中广泛的应用,所以留意所有能利用它们的机会。
最后,最令人期待的iOS 8新功能之一:LocalAuthentication。自从iPhone 5S加入TouchID,开发者就对它的应用前景垂涎三尺。
想象一下,只要有CloudKit和LocalAuthentication,创建新账号的烦恼讲不复存在。只需要扫描一下你的手就搞定了!
LocalAuthentication以LAContext的方式工作,验证声明的规格,然后返回是否验证成功。整个过程中,用户的生物信息都被安全的储存在硬件当中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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,很多只是细微的改变或者将方法改为属性,但是,它们值得拥有!
标签:
原文地址:http://www.cnblogs.com/lihaibo-Leao/p/4949738.html