在iOS上使用swift消耗REST API时出错

时间:2016-03-03 19:51:05

标签: ios xcode swift

我是iOS开发的新手,我正在学习本教程:https://grokswift.com/simple-rest-with-swift/而且我不知道为什么以下代码总会返回"占位符"我无法在控制台的输出中看到错误:

import Foundation

class Resolver{
    func doSomething() -> String{
        var result = "the placeholder"
        print("inside doSomething")
        let postEndpoint: String = "http://jsonplaceholder.typicode.com/posts/1"
        guard let url = NSURL(string: postEndpoint) else {
            print("Error: cannot create URL")
            return "error here"
        }

        let urlRequest = NSURLRequest(URL: url)

        let config = NSURLSessionConfiguration.defaultSessionConfiguration()

        let session = NSURLSession(configuration: config)
         print("another thing")

        let task = session.dataTaskWithRequest(urlRequest, completionHandler: {
            (data, response, error) in
            guard let responseData = data else {
                print("Error: did not receive data")
                return
                //return "error here"
            }
            print("hereeeeeee ############")
            guard error == nil else {
                print("error calling GET on /posts/1")
                print(error)
                return
                //return "error here"
            }
            // parse the result as JSON, since that's what the API provides
            let post: NSDictionary
            do {
                post = try NSJSONSerialization.JSONObjectWithData(responseData,
                    options: []) as! NSDictionary
            } catch  {
                print("error trying to convert data to JSON")
                return
                //return "error here"
            }
            // now we have the post, let's just print it to prove we can access it
            print("The post is: " + post.description)
            result = post.description

            // the post object is a dictionary
            // so we just access the title using the "title" key
            // so check for a title and print it if we have one
            if let postTitle = post["title"] as? String {
                print("The title is: " + postTitle)
            }

        })
        task.resume()

        return result
    }    

}

这是我的info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleIdentifier</key>
    <string></string>
    <key>CFBundleExecutable</key>
    <string></string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>LSApplicationCategoryType</key>
    <string></string>
    <key>CFBundleName</key>
    <string></string>
    <key>CFBundleDisplayName</key>
    <string></string>
    <key>CFBundleVersion</key>
    <string></string>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>httpbin.org</key>
            <dict>
                <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
            <key>jsonplaceholder.typicode.com </key>
            <dict>
                <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>
    <key>CFBundleShortVersionString</key>
    <string></string>
    <key>CFBundleGetInfoString</key>
    <string></string>
</dict>
</plist>

当我运行测试时,我看到了这个输出:

Test Suite 'RestTest' started at 2016-03-03 15:38:49.364
Test Case '-[FoodTrackerTests.RestTest testResolver]' started.
inside doSomething
another thing
// I want to see the result: the placeholder
Test Case '-[FoodTrackerTests.RestTest testResolver]' passed (0.061 seconds).
Test Suite 'RestTest' passed at 2016-03-03 15:38:49.425.
     Executed 1 test, with 0 failures (0 unexpected) in 0.061 (0.062) seconds
Test Suite 'Selected tests' passed at 2016-03-03 15:38:49.426.
     Executed 1 test, with 0 failures (0 unexpected) in 0.061 (0.063) seconds

为什么结果变量不包含post.description值?

2 个答案:

答案 0 :(得分:0)

doSomething()方法在异步调用完成之前返回"the placeholder"值。这就是你看到它的原因。

答案 1 :(得分:0)

正如评论中所建议的那样,在返回HTTP调用之前看起来测试正在完成(因为HTTP请求是异步的),因此在测试运行结束之前您没有看到API调用的结果。

查看XCAsyncTestCase并设置测试以等待异步回调。