10

我有一个包含 JSON 文件的网页地址。我正在尝试在 Swift 2 中以 NSDictionary 的形式访问 JSON 文件。每次我调用 NSData(contentsOfURL:url!)where urlis type of 时NSURL?,它都会返回nil. 我正在使用 Xcode 7 Beta,该项目最初是在 Xcode 6 中制作的。

以下代码导致问题。

let url = NSURL(string:myurl) // myurl is the webpage address.
let data = NSData(contentsOfURL:url!) // the bit that returns nil
// data is set to nil
// I would perform NSJSONSerialization.JSONObjectWithData later.

令我困惑的是,当我在终端中使用 键入相同的代码时尝试完全相同的事情时swift,该常量data未设置为 nil。我已经尝试重新启动 Mac,但它没有工作。我尝试重新安装 Xcode,但它没有工作。

这就是当我使用swift关键字向终端键入以下代码时发生的情况。

$> swift
......
Welcome to Apple Swift version 2.0 (700.0.38.1 700.0.53). Type :help for assistance. 

1> import Foundation
2> var urlstr = "http://mywebsiteaddress/jsonfile.json"
3> var nsurl = NSURL(string:urlstr)
nsurl: NSURL? = "http://mywebsiteaddress/jsonfile.json"{
    ObjectiveC.NSObject = {...}
}
4> var nsdata = NSData(contentsOfURL:nsurl!)
nsdata: NSData? = 5925 bytes {
    ObjectiveC.NSObject = {...}
}
5> print(nsdata)
Optional(<Some Values..........>)

当我在终端中尝试时,它确实有效。谁能帮我解决问题??

4

1 回答 1

13

我希望它可以在终端中运行,因为您在这里看到的可能不是 Swift 或 Cocoa Touch 中的错误,而是 iOS 9 中名为App Transport Security的新功能的副作用。这意味着默认情况下,iOS 不允许您向未使用 SSL 保护的服务器发出请求。

引用链接:

应用传输安全 (ATS) 允许应用将声明添加到其 Info.plist 文件中,该文件指定需要与其进行安全通信的域。ATS 可防止意外泄露,提供安全的默认行为,并且易于采用。无论您是创建新应用还是更新现有应用,都应尽快采用 ATS。

如果你正在开发一个新的应用程序,你应该只使用 HTTPS。如果您有一个现有的应用程序,您现在应该尽可能多地使用 HTTPS,并制定一个计划以尽快迁移您的应用程序的其余部分。

要解决此问题,您可以编辑 info.plist 文件以逐个域进行例外处理,或完全禁用 App Transport Security。这是引用自CFNetwork SSLHandshake failed iOS 9 Beta 1的示例。

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow insecure HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

尽管我建议您实际上不要将其用作您的解决方案,而是使用 SSL 安全的 https URL。

于 2015-06-15T16:28:04.610 回答