By Liang


2015-07-07 09:02:16 8 Comments

class PostFOrData {
    let url = NSURL( string: "http://210.61.209.194:8088/SmarttvWebServiceTopmsoApi/GetReadlist")
    var picUrl = NSURL(string : "http://210.61.209.194:8088/SmarttvMedia/img/epi00001.png")
    var responseString : NSString = ""

    func forData() -> NSString {

        let request = NSMutableURLRequest( URL: url!)
        request.HTTPMethod = "POST"
        var s : NSString = ""

        let postString : String = "uid=59"
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            if error != nil {
                println("error=\(error)")
                return
            } else {
                println("response = \(response!)")
                self.responseString = NSString(data: data, encoding: NSUTF8StringEncoding)!
                println("responseString = \(self.responseString)")
            }

        }

        // I want to return NSString here, but I always get nothing

        return self.responseString

    }
}

Anyone know how to get the data from task?

1 comments

@ayaio 2015-07-07 09:20:10

You can't return data directly from an asynchronous task.

The solution with Swift 2 is to make a completion handler like this:

class PostFOrData {
    // the completion closure signature is (NSString) -> ()
    func forData(completion: (NSString) -> ()) {
        if let url = NSURL(string: "http://210.61.209.194:8088/SmarttvWebServiceTopmsoApi/GetReadlist") {
            let request = NSMutableURLRequest( URL: url)
            request.HTTPMethod = "POST"
            let postString : String = "uid=59"
            request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
            let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
                data, response, error in
                if let data = data,
                    jsonString = NSString(data: data, encoding: NSUTF8StringEncoding)
                    where error == nil {
                        completion(jsonString)
                } else {
                    print("error=\(error!.localizedDescription)")
                }
            }
            task.resume()
        }
    }
}


let pfd = PostFOrData()

// you call the method with a trailing closure
pfd.forData { jsonString in
    // and here you get the "returned" value from the asynchronous task
    print(jsonString)
}

That way, the completion is only called when the asynchronous task is completed. It is a way to "return" the data without actually using return.

Swift 3 version

class PostFOrData {
    // the completion closure signature is (String) -> ()
    func forData(completion:  @escaping (String) -> ()) {
        if let url = URL(string: "http://210.61.209.194:8088/SmarttvWebServiceTopmsoApi/GetReadlist") {
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            let postString : String = "uid=59"
            request.httpBody = postString.data(using: String.Encoding.utf8)
            let task = URLSession.shared.dataTask(with: request) {
                data, response, error in
                if let data = data, let jsonString = String(data: data, encoding: String.Encoding.utf8), error == nil {
                    completion(jsonString)
                } else {
                    print("error=\(error!.localizedDescription)")
                }
            }
            task.resume()
        }
    }
}


let pfd = PostFOrData()

// you call the method with a trailing closure
pfd.forData { jsonString in
    // and here you get the "returned" value from the asynchronous task
    print(jsonString)
}

@Honey 2016-06-26 22:10:05

1) That was quick for Swift 3! 2) coming from an Objective-C background, it's a bit confusing. You don't see any completionHandler keyword in Swift. Is that something inferred?

@user1956608 2016-08-21 19:00:05

Yes. It's standard Swift syntax. If a closure is defined at the end of a function the closure can be defined after the closing ')' bracket and the parameter name excluded. They're called trailing closures. See developer.apple.com/library/mac/documentation/Swift/Conceptu‌​al/…

Related Questions

Sponsored Content

15 Answered Questions

[SOLVED] How to call Objective-C code from Swift

  • 2014-06-02 20:05:42
  • David Mulder
  • 255232 View
  • 870 Score
  • 15 Answer
  • Tags:   objective-c swift

9 Answered Questions

[SOLVED] How to detect tableView cell touched or clicked in swift

2 Answered Questions

[SOLVED] URL nil after upgrade to swift 3.0

1 Answered Questions

[SOLVED] swift http request crash nil value

  • 2016-10-13 12:37:32
  • MattBlack
  • 65 View
  • -2 Score
  • 1 Answer
  • Tags:   swift http

1 Answered Questions

0 Answered Questions

1 Answered Questions

1 Answered Questions

[SOLVED] Swift downloading data from web

  • 2015-03-24 09:35:52
  • Stevik
  • 819 View
  • 5 Score
  • 1 Answer
  • Tags:   swift

1 Answered Questions

[SOLVED] how to use JsonArray out of Queue

Sponsored Content