String Nil Inside Nsurlsession

String nil inside NSURLSession

The reason your variable is nil is because closures are executed asynchronously. That means that the rest of the code after the network request will continue to be called as normal, but the code containing parameters data, response and error is only called when the network request is finished.

To work around this, try putting whatever you are trying to do with the variable inside the closure, so your println(testString) would be inside the curly brackets.

Why does NSHTTPURLResponse return nil? NSURLSession, Swift 2.2

func dataTaskWithRequest(_ request: NSURLRequest,
completionHandler completionHandler: (NSData?,
NSURLResponse?,
NSError?) -> Void) -> NSURLSessionDataTask

The initial method takes an NSURLResponse. This is the response of the requested URL. NSURLResponse can be of any kind of response.

NSHTTPURLResponse is a subclass of NSURLResponse, you can cast your response to NSHTTPURLResponse only if you are sure that your webservice encode responses using the HTTP protocol. Otherwise, the cast will always return nil.

Also, I'm seeing that the Webservice that you are using has some restrictions of usage :

How to get accurate API response

1 Do not send requests more then 1 time per 10 minutes from one device/one API key. Normally the weather is not changing so
frequently.

2 Use the name of the server as api.openweathermap.org. Please never
use the IP address of the server.

3 Call API by city ID instead of city name, city coordinates or zip
code. In this case you get precise respond exactly for your city.

4 Free account has limitation of capacity and data availability. If
you do not get respond from server do not try to repeat your
request immediately, but only after 10 min. Also we recommend to store
your previous request data.

Now I'm thinking that your problem could come from there.

URL nil after upgrade to swift 3.0

Try this:

let firstResult = "San Francisco, California, United States"
print(firstResult)
if let correctedAddress = firstResult.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: "https://maps.googleapis.com/maps/api/geocode/json?address=\(correctedAddress)") {
print(url)
}

NSURLSession crash with JSON data parameter is nil while error is managed

You should just add a if block after before initizaling your JSON. Such as:

if(rawData != nil) {
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:dataRaw
options:kNilOptions error:&error];
}

After that you can handle your error if it is not nil.

Swift / NSURLSession JSON download / unexpectedly found nil while unwrapping an Optional value

Your problem is in these 2 lines:

let dollarToDollarNSNumber = dollarToDollarDict.valueForKey("EUR")
let dollarToDollarString = String(dollarToDollarNSNumber)

dollarToDollarDict.valueForKey("EUR") returns an optional, so dollarToDollarNSNumber is an optional.

Calling the String initializer with an optional gives the string "Optional(...)" so when you later pass that string to the Double initializer it fails because it has letters in it.

You need to unwrap the value you get from valueForKey by doing something like this:

if let dollarToDollarNSNumber = dollarToDollarDict.valueForKey("EUR") {
let dollarToDollarString = String(dollarToDollarNSNumber)
SpeedLog.print(dollarToDollarString)
self.dollarExchangeRateStr = dollarToDollarString
} else {
self.dollarExchangeRateStr = ""
}

Why my return is nil but if i press the url in chrome/safari, i can get data?

The text you try to get is probably not UTF-8, try with another encoding, like this for example:

let myString = NSString(data: data, encoding: NSASCIIStringEncoding)

Update: read Martin R's answer for how to find the right encoding.

NSURLSession Response String completion block - Swift

The convenience method of dataTaskWithRequest essentially returns data or error, with usually some response header type information. If you have an error then you won't have data (99% sure about this). I have re formatted your method to help. The NSString Init Convenience method is synchronous so not quite sure by what you mean by waiting to complete instead of http call?

func getStringFromRequest(completionHandler:(success:Bool, data: NSData?) -> Void) {

let request = NSMutableURLRequest(URL: NSURL(string: "http://##.##.##.##/EPG/XML/QueryProfile")!)
request.HTTPMethod = "POST"
let postString = "<QueryProfileReq><type>1</type></QueryProfileReq>"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

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

if let unwrappedError = error {
print("error=\(unwrappedError)")
}
else {
if let unwrappedData = data {
completionHandler(success: true, data: unwrappedData)
return
}
}

completionHandler(success: false, data: nil)
}

task?.resume()
}

func performPost() {

getStringFromRequest { (success, data) -> Void in

if (success) {

if let unwrappedData = data {

self.dataVar = unwrappedData

if let responseString = NSString(data: unwrappedData, encoding: NSUTF8StringEncoding) {
self.nextScreen()
}
}
}
else {
print("Failed")
}
}
}

Return value in NSURLSession Error

You can use this method with block like this :

-(void)callAPIWithCompletionHandler : (void (^) (NSString * strResponse)) completionHandler
{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:@"http://appersgroup.com/talkawalk/login.php?email=twalknet@gmail.com&password=123456&latitude=52.486245&longitude=13.327496&device_token=show"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];

[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];

[request setHTTPMethod:@"POST"];
/* NSDictionary *mapData = [[NSDictionary alloc] initWithObjectsAndKeys: @"TEST IOS", @"name",
@"IOS TYPE", @"typemap",
nil];
NSData *postData = [NSJSONSerialization dataWithJSONObject:mapData options:0 error:&error];
[request setHTTPBody:postData];
*/

NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

NSString* responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

if([responseString rangeOfString:@"nil"].location != NSNotFound)
{
NSString * newResponse = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

responseString = newResponse;
}

NSLog(@"%@",responseString);
NSLog(@"response %@",response);
NSLog(@"error %@",error);

completionHandler(responseString);

}];

[postDataTask resume];
}

Call this method and return response as below :

[self callAPIWithCompletionHandler:^(NSString *strResponse) {

NSString *responseString = strResponse;
}];

Suppose this method implemented in ViewControllerA, and you want to call this from ViewControllerB.

Then import ViewControllerA in ViewControllerB and make instance of ViewControllerA in ViewControllerB.

ViewControllerA *vcA = [[ViewControllerA alloc] init];
[vcA callAPIWithCompletionHandler:^(NSString *strResponse) {

NSString *responseString = strResponse;
}];


Related Topics



Leave a reply



Submit