30 8月

苹果官方博客:从SDK详说Swift代码的改变

文 / Apple Inc.     原文链接:Apple Developer’s Blog

Xcode 6.3中,我们为Objective-C添加了新语言特性nullability注解。这个特性给Objective-C提供了表达API使用null和non-null统一的方式。相当于Swift语言中的Optional类型。Xcode 7继续为Objective-C与Swift之间更加自然地通信引入轻量级的泛型模型。泛型使得这两种语言能够可靠地融合并分享带有特定类型元素的集合。

这些特性对任何使用Swift和Objective-C这两种语言编程的人来说都比较有用。但应用程序开发人员每天使用的Objective-C代码占更大部分:这就是组成Apple SDK的那些框架。为了提升Swift和Objective-C的使用体验,全公司的范围内,我们在SDK的头文件中都提供了这样的信息。Xcode 7中,你会发现几乎所有常见框架都指定了其API的nullability注解,包括其集合类型的元素。这使得Swift代码的样子发生了变化。

变化前:

  1. class UIView : UIResponder {
  2.     init!(frame: CGRect)
  3.     var superview: UIView! { get }
  4.     var subviews: [AnyObject]! { get }
  5.     var window: UIWindow! { get }
  6.     // …
  7.     func isDescendantOfView(view: UIView!) -> Bool
  8.     func viewWithTag(tag: Int) -> UIView!
  9.     // …
  10.     var constraints: [AnyObject]! { get }
  11.     // …
  12. }

变化后:

  1. class UIView : UIResponder {
  2.     init(frame: CGRect)
  3.     var superview: UIView? { get }
  4.     var subviews: [UIView] { get }
  5.     var window: UIWindow? { get }
  6.     // …
  7.     func isDescendantOfView(view: UIView) -> Bool
  8.     func viewWithTag(tag: Int) -> UIView?
  9.     // …
  10.     var constraints: [NSLayoutConstraint] { get }
  11.     // …
  12. }

最后一个疑问是Xcode 7中将代码转换成Swift 2的工具,在Xcode的Edit菜单下,Convert > To Latest Swift Syntax。通过必要的编辑,该工具会将一个使用Swift 1.2编写的项目转换成合法的Swift 2.0代码。这些改变源于改进后的头文件信息。例如,正在重写的一个方法,其参数和结果类型更加精确,方法转换的过程中将会被更新与之匹配。

在今年的WWDC的Swift and Objective-C Interoperability视频14:30处,对Objective-C所作的改进做了详尽的描述。注意,该视频使用的是Xcode 6.3中的__nullable语法,并非更新的Xcode 7中用的_Nullable。了解更多nullability注解的信息,可以看看Nullability and Objective-C。了解Swift 2.0和Objective-C中轻量级泛型更多信息,可以看看Xcode 7 Release Notes

http://www.csdn.net/article/2015-08-17/2825473-swift-er-sdk

09 8月

Stripe使用指南:Swift开发中的信用卡支付

文 / Ziad Tamim:资深iOS开发人员,创业公司移动战略咨询顾问。自App Store上线以来,编写超过80款应用程序。目前,他经营着一家叫做TAMIN LAB的移动开发工作室。

原文链接:http://www.appcoda.com/ios-stripe-payment-integration/

在这篇文章中,我们来谈谈Stripe的集成。Stripe提供了程序库来接受在线及移动应用支付行为,是功能最为强大的程序库之一。如果你计划在iOS应用中出售产品,或者在寻找一种支付解决方案,那么Stripe应该是你的首选。

很多iOS开发人员问我,为什么要选择Stripe而不是应用内购买(In-App Purchase)。根据苹果公司的规定,出售数字化内容需要使用应用内购买,像电子游戏附带的游戏级别,应用给予用户的虚拟物品。对于像衣服这样的实物,则允许使用像Stripe 这样的其他支付方案。所以,在这篇文章中,我会简要介绍Stripe,并解释它是如何工作的,告诉你如何使用Stripe的API构建一个示例,用来接受信用卡的支付行为。
stripe-integration-tutorial

Stripe为何物?

Stripe为开发人员构建,提供友好的API,使商家能够立即接受并管理移动支付行为。而不必为开设商业账户,设立信用卡网关而费心费力。有了Stripe,你可以轻松地实现应用的信用卡支付功能,甚至是重复付款。

Stripe意在使在线/移动交易唾手可得。你很快就会看到,在方便易用的API顶端,Stripe甚至精简了注册流程,集成过程就是这么简单!这就是该公司为什么能够如此迅速地扩张,名列2015十大创业公司行列的原因。

我们的应用程序

为了避免从头构建应用浪费时间,把注意力集中在学习Stripe上,我创建了项目模版。首先,下载项目并运行一下。

在本文中,我们将会创建一个叫做“Donate”的示例,演示如何使用Stripe接受信用卡付款。

iOS-Simulator-Screen-Shot-Jun-9-2015-5.35.27-PM-576x1024

编辑注:此应用为示例程序,根据苹果公司的App Store Review Guidelines,如果应用带有捐款功能,应用本身应当免费,必须通过网站的Safari页面或SMS服务完成公益款项的筹集。

应用的业务周期及Stripe的工作原理

深入实现之前,我们先看看应用如何与Stripe通信,如何处理事务。简而言之,用户发送支付请求的时候,应用如何工作:

1. 应用首先收集支付信息,包括电子邮件、信用卡号码、有效期、CVC(Card Validation Code)和支付表单上的支付金额。然后通过调用Stripe的API将这些信息发送给自己的服务端。

2. 如果支付信息有效,那么Stripe就会返回一个令牌(token)。此时,信用卡还没有被扣费。随后你会使用令牌执行实际的交易。

3. 现在应用获得了令牌。下一步是将其发送到本地服务器来完成扣费的过程。出于安全原因,Stripe需要通过服务器来进行扣费,而不是移动设备本身。不过不用担心,Stripe为我们提供了服务代码,可以轻松完成扣费过程。我们会在后面的小节讨论。

4. 你的本地服务器发送令牌到Stripe来执行实际的扣费操作。无论交易成功与否,Stripe都会返回结果。

5. 最后,本地服务器将有关交易结果的响应返回给应用。

stripe-flow

注:返回的响应是JSON格式的,所以如果不熟悉JSON解析的话,可以查看这个教程

创建一个Stripe测试帐号

创建一个Stripe测试帐号非常简单,可以在几秒钟内完成。Stripe可以简化整个注册过程,注册一个帐号不需要填写任何信息。我真的很喜欢这种精简的流程。如果你正在为客户开发应用,或者仅打算探索一下Stripe的API,这样的流程再好不过了。

第一步是去Stripe的网站,点击sign up按钮:

stripe-signup

你将被引导到注册页面创建一个新的帐号,在这里可以填写个人信息。但正如我之前提到的,Stripe精简了注册流程,可以在这里简单地单击“skip this step”继续。你将能够通过一个以测试为目的的临时帐号访问Stripe的Dashboard页面。

Screen-Shot-2015-06-09-at-9.05.20-PM-e1433890510184

一旦完成这个过程,Stripe的Dashboard页面就会呈现在你面前:

stripe-dashboard

接下来,点击菜单中的“Your Account”,点击“Account Settings”,然后点击“API Keys”选项卡,会显示用于应用开发的Key。

Screen-Shot-2015-06-10-at-12.05.31-AM

这就是Stripe的配置过程。从现在开始,你就可以使用Stripe的API来测试交易了。以后还可以回到Dashboard页面检查交易是否被成功处理了。

使用CocoaPods添加Stripe库

在Xcode工程使用Stripe之前,我们必须将库引入作为一个依赖项。有几个方法可以做到这一点。在示例中,我们将使用CocoaPods,它是一个著名的Swift项目依赖管理工具。就像这个示例,很多项目都依赖于第三方库工作。CocoaPods是一种工具,有助于开发人员管理所需的依赖库,确保这些库是最新的。

如果还没有安装CocoaPods,可以在终端执行下面的命令安装:

sudo gem install cocoapods

只要有耐心,只要等待几分钟的时间就能完成安装。安装完成后,你可以看到“”gems installed这样的字眼儿。

Screen-Shot-2015-06-10-at-4.09.48-PM

接下来,在Xcode工程根目录下创建一个名为“Podfile”的文件,使用你喜欢的文本编辑器打开它,把下面两行复制进来:

pod 'Stripe', '~> 4.0'
pod 'AFNetworking', '~> 2.5.4'

Podfile告诉CocoaPods我们想使用哪个库。我们这里需要是Stripe 4.0和AFNetworking 2.5.4。

现在,退出Xcode,打开Terminal,更改Xcode的根目录。根目录是“Podfile”所在目录。接下来,在Terminal键入:

pod install

CocoaPods将寻找“Podfile”,尝试安装我们所设置的依赖项。下载和安装的过程可能要持续几分钟。完成后,结果应该是这样的:

Screen-Shot-2015-06-10-at-4.28.31-PM

CocoaPods下载完毕,在Xcode项目中引入了Stripe和AFNetworking。然而,从现在起,我们不会再使用原始应用项目了。CocoaPods生成了另一个叫做Donate.xcworkspace的工作区。这个工作区包含了原始项目和CocoaPods管理的项目。

现在打开Xcode中新的工作区(也就是Donate.xcworkspace),你应该注意到一共有两个项目:Pods和Donate。

cocoapod-projects

在Swift项目中使用Objective-C

Stripe的库是用Objective-C写的,而我们的项目使用Swift。不进行适当的配置,这两种语言无法一起工作。通过建立桥接头文件(briddging header),任何Objective-C的库,项目和类都可以在Swift项目中使用。从技术角度来说,这样的关联会把头文件从Objective-C转换成Swift。

通过以下步骤可以创建一个桥接头文件:

  1. 在Donate路径中添加一个新的头文件。对准项目导航器中的Donate右击,然后点击“New File…”。
  2. 选择iOS -> Source分类,选择“Header File”模版,然后点击“Next”。
  3. 将类命名为“Donate-Bridging-Header.h”,点击继续,进行下一步并保存文件。
  4. 接下来,去“Building Settings”,找到“Objective-C Bridging Header”,将值设置为“Donate/Donate-Bridging-Header.h”。

Screen-Shot-2015-06-10-at-4.37.23-PM-1024x312

完成后,打开Donate-Bridging-Header.h文件,编写如下代码:

#import <Stripe/Stripe.h>
#import <AFNetworking/AFNetworking.h>

太棒了!终于完成了项目的配置。我们现在已经做好准备,进入示例程序的实现阶段。

设置API Key

你要做的第一件事就是配置Stripe的API Key。在Stripe的Dashboard页面,你可以点击“Account Settings” -> “API keys”来找到你的Key。现在,我们将使用用于测试的Key,这样你就可以不用真实的信用卡也可以测试交易过程了。

打开AppDelegate.swift文件,在里面插入一行代码(第3行):

  1. func application(application: UIApplication, did-FinishLaunchingWithOptions launchOptions: [NSOb-ject: AnyObject]?) -> Bool {
  2.      // Stripe Configuration
  3.      Stripe.setDefaultPublishableKey(“pk_test_IeR8DmaKtT6Gi5W7vvySoCiO”)
  4.      return true
  5. }

这里使用的是我们用于测试的Test Publishable Key,别忘了你要改成自己的。

注意:以后在实际应用程序中,你可以将Test Publishable Key换成Live Publishable Key。

收集信用卡信息

要进行交易,应用要有一个收集用户信息的环节。Stripe建议通过三种方法收集付款信息:

  • 通过Apple Pay访问用户所存储的支付信息
  • 通过Stripe内置的支付表单组件,PaymentKit
  • 通过构建自己的支付表单

在本文中,我们选择第三种方式,构建我们自己的支付表单。Stripe至少需要收集信用卡号和其有效期。但我也建议要保护CVC的安全,防止欺诈性交易,并获得用户的信任。你可能想要获得另一条信息是电子邮件地址,这样你就可以留有捐款者的记录以备后续沟通。

如果你用的是项目模版,我已经在其中建立了支付接口来收集用户的支付细节。所有的文本字段都与ViewController.swift文件中对应的outlet关联了。

donate-app-storyboard

现在,打开ViewController.swift,更新donate方法:

  1. @IBAction func donate(sender: AnyObject) {
  2.         // Initiate the card
  3.         var stripCard = STPCard()
  4.         // Split the expiration date to extract Month & Year
  5.         if self.expireDateTextField.text.isEmpty == false {
  6.             let expirationDate = self.expireDateTextField.text.componentsSeparatedByString(“/”)
  7.             let expMonth = UInt(expirationDate[0].toInt()!)
  8.             let expYear = UInt(expirationDate[1].toInt()!)
  9.             // Send the card info to Strip to get the token
  10.             stripCard.number = self.cardNumberTextField.text
  11.             stripCard.cvc = self.cvcTextField.text
  12.             stripCard.expMonth = expMonth
  13.             stripCard.expYear = expYear
  14.         }
  15. }

当用户点击Donate按钮时,该动作方法将被触发。我们首先初始化一个STPCard对象,并进行赋值。

下一步,在同样的方法中添加如下代码:

  1. var underlyingError: NSError?
  2. strip-Card.validateCardReturningError(&underlyingError)
  3.    if underlyingError != nil {
  4.         self.spinner.stopAnimating()
  5.         self.handleError(underlyingError!)
  6.    return
  7. }

STPCard类有非常方便的方法validateCardReturningError,我们就不用实现自己的验证逻辑了。类将收集到的信用卡信息发送给服务器,如果卡片信息是无效的,就会返回一个错误(error)。

像上面一样,将下面的代码添加到统一的方法中:

  1. STPAPICli-ent.sharedClient().createTokenWithCard(stripCard, completion: { (token, error) -> Void in
  2.             if error != nil {
  3.                 self.handleError(error!)
  4.                 return
  5.             }
  6.             self.postStripeToken(token!)
  7.         })

一旦确认信用卡有效,我们就调用STPAPIClient类的createTokenWithCard方法,通过安全的HTTPS请求发送信用卡数据。如果请求成功,Stripe将返回一个令牌。

这个时候用户的信用卡还没发生扣费。Stripe仅仅给了你一个一次性的令牌。稍后你将这个令牌发送到本地服务器去执行实际的扣费。

如果无法获取令牌,应用会简单地向用户显示一个错误信息。还是在同一个文件中,ViewController类中需要插入如下代码:

  1. func handleError(error: NSError) {
  2.         UIAlertView(title: “Please Try Again”,
  3.             message: error.localizedDescription,
  4.             delegate: nil,
  5.             cancelButtonTitle: “OK”).show()
  6.     }

建立本地服务器

本文刚开始的时候提到过,用户的信用卡扣费实际发生在我们自己的服务器上。出于安全原因,Stripe不直接从应用程序对信用卡进行扣费。Stripe只是生成一个令牌。应用将这个令牌传递给本地服务器进而进行实际的扣费。

所以在实现应用程序这一步之前,让我们停留片刻,建立自己的本地服务器来处理付款。为了创建自己的服务端,我们将使用PHP作为主要的编程语言,并利用Stripe提供的库。不用担心,你不必是一位Web开发的行家,跟着所描述的步骤走,就能配置处理Stripe支付所需要的服务端。

首先,下载XAMPP (for OS X) v5.6.8 (or up),在Mac上安装。接下来,下载这个压缩文件并解压缩。找到XAMPP的安装目录,通常安装在“Applications”文件夹。打开“Applications/XAMPP/htdocs”,拷贝压缩后的文件夹。

xampp-donate-htdoc

完成以后,返回XAMPP文件夹,打开“manager-osx”。在“Manage Servers”标签下点击“Start All”,服务就启动了:

xampp-manager

下一步就是去“Applications/XAMPP/htdocs/donate”,使用你喜欢的任意文本编辑器打开文件“payment.php”。

用Test Secret Key将方法中的参数替换掉,这在本文中已做描述:

\Stripe\Stripe::setApiKey("sk_test_qCTa2pcFZ9wG6jEvPGY7tLOK");

搞定了!你刚才已经完成了服务端的配置,简单吧?

给服务端发送令牌进行支付处理

现在,我们的本地服务器准备处理付款。我们回到Xcode,通过发起一个HTTP POST请求给本地服务器开始发送令牌。打开ViewController.swift,在文件中插入代码:

  1. func postStripeToken(token: STPToken) {
  2.         let URL = “http://localhost/donate/payment.php”
  3.         let params = [“stripeToken”: token.tokenId,
  4.             “amount”: self.amountTextField.text.toInt()!,
  5.             “currency”“usd”,
  6.             “description”: self.emailTextField.text]
  7.         let manager = AFHTTPRequestOperationManager()
  8.         manager.POST(URL, parameters: params, success: { (operation, responseObject) -> Void in
  9.             if let response = responseObject as? [String: String] {
  10.                 UIAlertView(title: response[“status”],
  11.                     message: response[“message”],
  12.                     delegate: nil,
  13.                     cancelButtonTitle: “OK”).show()
  14.             }
  15.             }) { (operation, error) -> Void in
  16.                 self.handleError(error!)
  17.         }
  18. }

由于我们在本地建立了服务端,那么就把URL设置为http://localhost/donate/payment.php。如果在远程主机中建立的服务端,请做相应的更改。

Stripe要求我们提交令牌来执行实际的扣费。外带付款额,币种和相关描述。你可以使用描述字段作为付款说明。在示例中,我们只是使用这个字段来存储用户的电子邮件。

一旦配置好参数,就使用AFHTTPRequestOperationManager提交一个异步的POST请求。这是AFNetworking提供的一个API。如果请求成功,我们就向用户显示支付响应。

这样就好啦!现在你可以运行应用程序并测试交易功能。出于测试目的,可以使用4242 4242 4242 4242这个信用卡号,还有任意的将来日期作为有效期(例如07/2019),包括CVC(例如222),这样可以模拟交易过程。

donate-stripe-success-300

为了进一步验证支付是否成功,可以看看Stripe的Dashboard:

Screen-Shot-2015-06-11-at-5.09.01-PM

总结

在本文中,我带着你学习了Stripe的基础知识。你应该学会了如何在应用中集成Stripe来接受信用卡的支付行为。为了进一步学习,我鼓励你去看看官方文档。Stripe提供了许多通过其API完成支付的方式,可以通过官方文档了解更多信息。

作为参考,可以从这里下载整个Donate项目,请使用Xcode 6.3(或以上)版本运行。别忘了把AppDelegate.swift文件中的Secret Key换成自己的。

http://www.csdn.net/article/2015-07-27/2825301-ios-stripe-payment-integration/1

27 7月

Swift 2.0概览

文 / Russ Bishop:全能型程序员,使用C#,Objective-C和Swift语言编程,开发了奇特的应用Storm Sim Free。

原文链接:http://www.russbishop.net/swift-2-0

毫无疑问,Swift 2.0在2015全球开发者大会(Worldwide Developers Conference, WWDC 2015)上被发布的消息众人皆知。我会就该语言所发生的变化撰写一系列的文章,但目前我们先说说重点。

常规变化

  • 现在全局函数和独立(free-standing)函数都和方法一样,遵循同一个参数标签规则。不再使用#这样的语法来引用外部资源。
  • 你基本上可以使用 enum SomeEnum<T,U,V>来声明 multi-payload 风格的枚举,这样就能正常运行。这用来提示未完成的指令寄存器(IR)引发的错误。
  • 条件循环语句目前的语法是 repeat { } while(cond),不再使用 do 。
  • 关键字 do 目前用来引入一个新的作用域(这对新引进的错误处理和 defer 关键字很重要)。在 C 语言中你可以用大括号,但 Swift 里就要理解为闭包(closure)。所以使用关键字 do 可以任意引入作用域。
  • guard 语句块显式地声明你要恒成立的条件语句,恒成立时跳过整个guard 语句。这样做的好处是绑定在guard语句的变量在函数的其他部分也可用。这就避免了将所有的东西都围绕一条if语句嵌套使用来解析(unwrap)可选类型的变量。执行到函数中guard语句中的else部分,函数一定会退出并抛出异常。也可能会调用带有@noreturn标记的函数。
  • 文本注释(doc comments)换成了Markdown格式,与Playgrounds统一(Playgrounds注释格式源于功能有限的reStructured Text)。
  • 编译器对冗余的协议一致性,未被使用的绑定值以及可以设为常量的变量这些情况目前会给予警告或报错。
  • Swift语言的调用约定更加智能,能够理解 API 所发生的变化和 Swift 所给出的警告。并且还可以升级(但还不是那么完美,一定还漏掉了一些东西)。
  • find函数改名为indexOf,sort则变成了sortInPlace,sorted变成了sort。
  • String不再直接遵循序列类型(SequenceType),大概是为了避免一些新的可用协议扩展。目的是迫使你使用s.characters,s.utf8或s.utf16明确你想处理的unicode编码。
  • 允许对泛型添加公共扩展。
  • 非泛型类类型可以继承泛型类(强制类型参数固定)。
  • 便利的可失败构造器(failable initializer)可以先返回nil,而不必首先调用self.init。这是有利的一面,但指定了构造器在返回nil前仍要给所有字段初始化。所以此处还有改进的余地。

内部的可见性

这解决了单元测试中的一个较大的难点。以前的做法:

  • Swift文件包含在test target中。现在不同的模块中有重复的类的定义,出现无法将“X”转换为“X”这样非常可怕的错误,有时会无法执行特定的测试。
  • 在测试中引入引入主程序(main program)作为一个模块。现在一切都声明为public,所以对于测试来说都是可见的,有时候也包括应该声明为private的内部细节。

现在可以启用testability,它就像C#中的 InternalsVisibleTo。主应用程序目标模块的内部细节对测试模块可见。

  • 在对应用或框架的测试设置中,启用testability。
  • 在单元测试中,使用@testable import {ModuleName}。

这将导致测试忽略某些优化行为并保留稍后导入到测试模块中的那些内部符号。官方文档警告说,由于阻止了某些优化,因此这只适用于调试和测试版本。

模式匹配

switch语句的模式匹配(pattern matching)语法和“if let …, …. where”语法一直在推广。可以在任何控制流中使用逗号操作符和where条件语句。还可以使用新的case条件语句,例如:if case .Silly(let a) { }。还有一种用于Optional<T>的特殊形式:if case let a? = anOptional { }。

模式匹配在循环语句中也可以使用:for case let thing? in array { }。

这又是值得单独成文的另一个特性。

Objective-C的泛型和__kindof的用法

在关于Swift的帖子里谈论这个做甚?它的作用是使某些衔接更加清晰和简便。不求在这篇文章中面面具到,我会在单起一篇文章阐述它。

错误处理

这不是我们一贯所认识的异常,这是一个使函数提前返回Result<T, Error>的操作,单隐藏了所有提前返回的对象,也隐藏了错误解析(error unwrapping)过程等内容。

  1. let systemAttributes: [NSObject: AnyObject]?
  2. do {
  3.     systemAttributes = try NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last!)
  4. catch _ {
  5.     systemAttributes = nil
  6. }

它完美地与Objective-C进行互操作,Swift语言中,将标记为throws的方法作为选择器。这是使用NSError的方法,-(BOOL or nullable type)someMethodTakingParam:(type)param error:(NSError **),这种样式会自动引入标记为throws的方法。

应该明白的是这并不像Java中已经被检查过的异常(checked exception)那样。Swift语言并不关心异常的类型,或者处理或者不处理。这又是值得单独成文的另一功能特性。

Defer关键字

关键字defer也很重要,因为它可以取代传统C风格的“if(err) goto cleanup”。获得资源后接着就是defer { release_resource() }。然后不管函数返回结果如何,获得的资源都将被清理。这也意味着资源的释放紧随获取资源之后。这看起来不起眼儿,实则很重要。

NS_OPTIONS和OptionSetType

位操作枚举(bitwise enumeration)与数组风格的语法相结合,而不使用管道符“ | ”按位操作,并且具有所有范围的集合操作功能。检查一下是否具有contains功能的标志,或能够执行像isSubsetOf和isDisjointWith等这样集合操作的其他功能。这是显著的改进,表达了不直接对位进行操作的意愿。

这种变化意味着位操作枚举实际上不再是枚举了。将这些位操作枚举声明为结构体,实现OptionSetType协议,提供rawValue属性。并且创建值作为结构体的静态成员。Swift便会搞定其余的一切,自动提供所有集合的操作。这是我希望将来看到的更加明了的语法内容。

协议扩展

协议如今可以被扩展了,包括与类型约束有关的通用协议。还可以自己提供协议的默认实现。

先前,你不能你说:“我要使用方法X来扩展CollectionType,但只有集合中的类型满足某些条件才可以”。现在,你可以这么做,并且很多像map,filter和sort这样的全局函数已经进行了扩展。

这样就解决了很多痛点,这也是值得单独成文的内容。同时,要看看WWDC的面向协议编程(Protocol Oriented Programming)了解一些细节。

API审计

大量的API已经进一步进行了审计而更合理。举几个例子:

  • UITableView的dequeueReusableCellWithIdentifier方法现在返回UITableViewCell?类型的对象。
  • UIKit的属性现在也被声明为了实际的属性。

用translatesAutoresizingMaskToConstraints = false 代替了setTranslatesAutoresizingMaskToConstrains(false)。

Availability属性

@available属性自Swift 1.2就存在了并且后续支持得很好。添加了一个新的陌生语法if#available(),为处理版本检查提供了支持。而不是插入你喜欢的方法。

遗憾的是你不能只声明一个属性 UISearchController并将target设置为iOS 7,然后只允许访问类中的属性。Swift希望整个类的定义都可以或者不可以。

也可以不再采用协议,除非支持target设置中所有的操作系统版本,除非将整个类标记为只在更新的操作系统版本可用。

这意味着使用if #available()存在单独的子类和对创建适当对象的保护。

尽管如此,我个人还是发现了一个Bug,应用在iOS4.0-4.1发生崩溃,由于编译器没有发出警告,方法只在iOS4.2才引入,因此我犹如与定时炸弹相伴。

C函数指针

Swift现在可以使用C函数指针,CFunctionPointer已不复存在。任何全局函数,嵌套函数和不捕获状态的闭包都可以作为一个C函数指针直接传递。你也可以调用来自C程序的函数。

你可以显示地使用新属性@convention(c),表示函数应该使用C调用约定,简单痛快!尽管我想不出在此对块(block)的支持有何用,作为所发生变化的一部分,@objc_block也被删掉了,使用@convention(block)取而代之。@convention(swift)默认支持所有函数和闭包。

这并不是编程语言所特有的。iOS 9含有不同版本的Swift标准库,并且在未来系统中将添加修正后的Swift标准库。结合新的App Thining技术,下载过程中苹果商店会将Swift标准库剥离出去的。我仍然在追根溯源地探求这究竟是如何工作的。

遗漏

明显的一个遗漏是处理异步代码。

苹果公司为我们提供了GCD,这是一个强大的基础类库,可以构建很多异步操作和并发原语。

然而,这些天我们做的每件事,构建用户接口和API都需要考虑异步性和并发性。我们把一个文件读操作锁定一段时间,对用户来说整个世界就都静止了。

这是个持续的痛点,不是多大的事儿,但如果经常性地每天重复,恐怕也是不行的。

C#和JavaScript都采用了async/await来为异步代码提供一流的语言支持。我想很多人都想知道,Swift会提供什么样的语法糖来帮助我们在实现异步操作方面确保正确性。我不知道在Swift 2.0发布的时间框架内是否会看到什么,但愿能有好的东西出现吧!

开放源码

宣布的内容中,反响最强烈的无疑是Swift开放源代码。苹果公司已经承诺在今年底前开放源码,我们也没有理由对此表示怀疑。与苹果公司编译器团队成员讨论过程中,他们看起来似乎对此由衷地兴奋,无论如何坚决要干成这件事(我有点小失望,他们没有打造出经典的苹果然后宣布开源,但我仍然对此消息发自内心地感到高兴)。

结论

Swift 2.0有很多令人喜爱之处。苹果公司的Swift团队向大家承诺他们会迅速行动。到目前为止这些承诺已经被兑现。成为苹果平台上的开发人员是一个激动人心的时刻。

http://www.csdn.net/article/2015-07-23/2825280-swift-2