How to Get Data from a Swift Nsurlsession

How to get data from a Swift NSURLSession?

I'm not sure NSString is the type you want. JSON may be format of the data returned, depending on your URL's functionality. I tried the code provided and got the same issues, but if you treat it as JSON (I used httpbin.org as a dummy URL source) and it worked.

    let task = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://httpbin.org/get")!, completionHandler: { (data, response, error) -> Void in
do{
let str = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! [String:AnyObject]
print(str)
}
catch {
print("json error: \(error)")
}
})
task.resume()

(thanks for suggested edit @sgthad. the edit is not particularly relevant to the question, but still wanted to update the code to be current.)

Update for Swift 3 syntax

let url = URL(string: "http://httpbin.org/get")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let unwrappedData = data else { return }
do {
let str = try JSONSerialization.jsonObject(with: unwrappedData, options: .allowFragments)
print(str)
} catch {
print("json error: \(error)")
}
}
task.resume()

How do I get the data from an NSURLSession as a string?

If your problem is that it is empty outside of the task, that is because it is going out of scope after the completion block ends. You need to save it somewhere that has a wider scope.

let url = NSURL(string: apiCall)
var dataString:String = ""
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
//I want to replace this line below with something to save it to a string.
dataString = String(NSString(data: data, encoding: NSUTF8StringEncoding))
dispatch_async(dispatch_get_main_queue()) {
// Update the UI on the main thread.
self.textView.text = dataString
});

}
task.resume()

now when you access dataString it will be set to the data from task. Be wary though, until task is completed, dataString won't be set, so you should really try to use it in the completion block.

How can I get the Data from NSURLSession.sharedSession().dataTaskWithRequest

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)
}

How to get value out of URLSession

The problem is that you are calculating finalPrice inside a closure, which is asynchronous. Your getGainLossNumber method however, is synchronous, so it actually returns before your closure is finished calculating finalPrice. Restructure your code so that getGainLossNumber takes a closure as a parameter, and invokes it once finalPrice has been calculated. Something like:

func getGainLossNumber(brand: String, quantity: Int, price: Double, _ completion: @escaping (Double) -> Void) {
APImodel.fetchData(brand: brand) { returnedDouble in
let currentPrice = returnedDouble

let finalPrice: Double
if quantity < 0 {
let orderQuantity = quantity * -1
finalPrice = price + (currentPrice*(Double(orderQuantity))*100)
}
else {
finalPrice = price - (currentPrice*(Double(quantity))*100)
}

completion(finalPrice)
}
}

Also note, that finalPrice does not need to be var as it will be assigned a value only once.

EDIT

Usage:

getGainLossNumber(brand: "brand", quantity: 1, price: 120, { finalPrice in
// You can access/use finalPrice in here.
}

Receive data from server in Json for Swift

From Swift 4, Swift has its own JSON Encoder and Decoder

Here is Apple's reference page. Check this out and figure out what you need.

and here is very simple sample code from me.

// YourTokenModel.swift
struct YourTokenModel: Decodable {
var token: String
}

// YourTokenController.swift
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = body.percentEscaped().data(using: .utf8)

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("There is a error while communication")
return
}

guard let data = data else {
print("No data comes out. Returning...")
return
}

do {
let decodedData = try JSONDecoder().decode(YourTokenModel.self, from: data)
print(decodedData.token)
// DO WHATEVER YOU WANT! //
} catch let error {
print("There is a error while decoding your JSON Model")
print(error)
}
}

task.resume()

How to get data from blocks using NSURLSession?

-(void)getJsonResponse:(NSString *)urlStr success:(void (^)(NSDictionary *responseDict))success failure:(void(^)(NSError* error))failure
{
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:urlStr];

// Asynchronously API is hit here
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"%@",data);
if (error)
failure(error);
else {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"%@",json);
success(json);
}
}];
[dataTask resume]; // Executed First
}

call this:

[self getJsonResponse:@"Enter your url here" success:^(NSDictionary *responseDict) {   
NSLog(@"%@",responseDict);
} failure:^(NSError *error) {
// error handling here ...
}];

Using Swift with URLSession works with GET and PUT, but it gives error 405 Method Not Allowed when I use POST

I find out the fix for my problem.

I was using "http://MY_ENDPOINT/validaResenha" in my constants file instead of using "https://MY_ENDPOINT/validaResenha".

After add the "s" to "http" letter (it becomes "https") everything starts to work for me.

The strange part is that GET and PUT methods works fine because of the redirect from HTTP to HTTPS, but in the case of POST calls, I got this error.

It's fixed now.



Related Topics



Leave a reply



Submit