Swift 2: NSData(contentsOfURL:url) 返回nil

10

我有一个包含JSON文件的网页地址,我想在Swift 2中将其作为NSDictionary访问。每次我调用 NSData(contentsOfURL:url!),其中urlNSURL?类型时,它都会返回 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..........>)

在终端尝试时,它肯定可以工作。有谁能帮我解决这个问题吗??


当您不从“swift”运行时,是否在沙盒模式下运行? - Aderstedt
1个回答

13

我认为在终端中应该可以正常工作,因为你在这里看到的问题很可能不是Swift或Cocoa Touch中的错误,而是iOS 9中一个名为App Transport Security的新功能的副作用。这意味着,默认情况下,iOS不允许您向未使用SSL进行保护的服务器发送请求。

引用自链接:

App Transport Security (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。


1
使用SSL安全的https URL代替+eleventy-zillion。 - rickster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接