Swift 2.0 NSURLConnection sendSynchronousRequest - xcode

I am using the code below to check for an internet connection. It was working correctly but after the Swift 2.0 update I now see an error on the line var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData? saying extra argument 'error' in call.
class func isConnectedToNetwork()->Bool{
var Status:Bool = false
let url = NSURL(string: "http://google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
var response: NSURLResponse?
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
Status = true
}
}
return Status
}
Do you have any ideas what I should change it to?
Thanks

If you look at apples documentation (https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/#//apple_ref/occ/clm/NSURLConnection/sendSynchronousRequest:returningResponse:error:) you'll see that the definition changed to this:
class func sendSynchronousRequest(_ request: NSURLRequest,
returningResponse response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>) throws -> NSData
They have removed the error parameter and the method throws now an ErrorType, if the request fails. So this should work:
do {
let data = try NSURLConnection.sendSynchronousRequest(request, returningResponse: &response)
} catch (let e) {
print(e)
}
However you shouldn't use this method: It's deprecated in favor of NSURLSession since iOS 9 and OS X 10.11.

Related

I want to load image Using method of NSURLConnectionDelegate and NSURLConnectionDataDelegate

I want to load images into connectionDidFinishLoading method and the method func connection(_connection: NSURLConnection, didReceive: Data) is not getting called
class ImageDownload: UIImageView,NSURLConnectionDelegate,NSURLConnectionDataDelegate
{
var imageSaved:UIImage!
var imageDownloaded:UIImage!
var connection2:NSURLConnection = NSURLConnection()
var data: NSMutableData = NSMutableData()
var urlstring:String = ""
var fileURL:URL!
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
var pathPlist:String!
func downloadImage()
{
let imgdownload :String = "http://image.tmdb.org/t/p/w500" + urlstring
// let urlnew: NSURL = NSURL(string: imgdownload)!
//print(urlnew,"url")
let url: NSURL = NSURL(string: imgdownload)!
let request1: NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
// let request2: NSMutableURLRequest = NSMutableURLRequest(url: urlnew as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)
connection2 = NSURLConnection(request: request1 as URLRequest, delegate: self, startImmediately: false)!
connection2.start()
}
func setURL(url:String) -> Void
{
print(url,"url")
urlstring = url
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
fileURL = documentsDirectory.appendingPathComponent(url)
print(fileURL,"fileurl")
if FileManager.default.fileExists(atPath: fileURL.path)
{
let image = UIImage(contentsOfFile: fileURL.path)
print("file exists")
self.image = image
}
else
{
downloadImage()
//let imgdownload :String = "http://image.tmdb.org/t/p/w500" + url
// let request = URL(string: imgdownload)
// let myUrl = NSURL(string: imgdownload)
//print("image loaded")
// self.image = self.imageSaved
}
}
func connection(_ connection: NSURLConnection, didReceive response: URLResponse)
{
print("in didReceive response\n")
self.data = NSMutableData()
}
func connection(_connection: NSURLConnection, didReceive: Data)
{
print("in didReceive data\n")
self.data.append(data as Data)
print(data,"image data is")
}
func connection(_ connection: NSURLConnection, didFailWithError error: Error)
{
print("connection error = \(error)")
}
func connectionDidFinishLoading(_ connection: NSURLConnection)
{
}
}*
I'm not familiar with the Swift syntax for NSURLConnection, so there's a nonzero chance I'm missing something subtle with the delegate method names, but off the top of my head, I see a couple of bigger problems:
Why are you using NSURLConnection in Swift? Every version of iOS that supports Swift also has NSURLSession. Just use the shared session, and your behavior will be almost identical to NSURLConnection.
You're using HTTP URLs. In all recent versions of iOS, you have to add special bits to your Info.plist if you want your app to be able to access HTTP URLs. I do not recommend doing that. Just use HTTPS.
You can get free TLS certs for HTTPS from Let's Encrypt. My guess is that as soon as you set that up and switch to an HTTPS URL, your problems will go away even with the existing code. But you should still be using NSURLSession.

Extra argument error in call [duplicate]

This question already has answers here:
Swift: Extra argument 'error' in call
(3 answers)
Closed 5 years ago.
I have been trying to login for a while using php but I have a final bug that stops me from finishing. It turns out to give a bug in NSJSONSerialization where the error tells me: error extra argument in call. Then I will provide a screenshot so that the error is clearer and the code so you can help me since I am in a blocking moment and I do not know how to solve it. Thanks in advance
Photo error: [
Code:
#IBAction func loginButtonTapped(sender: AnyObject) {
let userEmail = userEmailTextField.text;
let userPassword = userPasswordTextField.text;
if(userEmail!.isEmpty || userPassword!.isEmpty) { return; }
let myUrl = NSURL(string: "http://localhost/billapp/userSignIn.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let postString = "userEmail=\(userEmail)&userPassword=\(userPassword)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil{
print("error=\(error)")
return
}
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error:NSError) as? NSDictionary
if let parseJSON = json {
var resultValue:String = parseJSON["status"] as String!;
print("result: \(resultValue)")
if(resultValue=="Success")
{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLoggedIn");
NSUserDefaults.standardUserDefaults().synchronize();
self.dismissViewControllerAnimated(true, completion: nil);
}
}
}
task.resume()
}
last error
You can follow the quick fix sugestions. Doing so will let you end up like this:
do {
var json = try JSONSerialization.jsonObject(with: Data(), options: .mutableContainers)
if let parseJSON = json {
//your code
}
} catch {
//handle error
}
Unlike Objective C, as per the new methodolgy in Swift, errors are handled using try/catch block instead of passing the error object in the method.
Use the following code for Swift 3.
do {
var json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
if let parseJSON = json {
var resultValue:String = parseJSON["status"] as String!;
print("result: \(resultValue)")
if(resultValue=="Success")
{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLoggedIn");
NSUserDefaults.standardUserDefaults().synchronize();
self.dismissViewControllerAnimated(true, completion: nil);
}
}
} catch let error {
//Perform the error handling here
}
Following for Swift 2
do {
var json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
if let parseJSON = json {
var resultValue:String = parseJSON["status"] as String!;
print("result: \(resultValue)")
if(resultValue=="Success")
{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLoggedIn");
NSUserDefaults.standardUserDefaults().synchronize();
self.dismissViewControllerAnimated(true, completion: nil);
}
}
} catch let error {
//Perform the error handling here
}

Swift URL POST request function with returning values [duplicate]

I am currently trying to download, parse and print JSON from an URL.
So far I got to this point:
1) A class (JSONImport.swift), which handles my import:
var data = NSMutableData();
let url = NSURL(string:"http://headers.jsontest.com");
var session = NSURLSession.sharedSession();
var jsonError:NSError?;
var response : NSURLResponse?;
func startConnection(){
let task:NSURLSessionDataTask = session.dataTaskWithURL(url!, completionHandler:apiHandler)
task.resume();
self.apiHandler(data,response: response,error: jsonError);
}
func apiHandler(data:NSData?, response:NSURLResponse?, error:NSError?)
{
do{
let jsonData : NSDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary;
print(jsonData);
}
catch{
print("API error: \(error)");
}
}
My problem is, that the data in
do{
let jsonData : NSDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary;
print(jsonData);
}
remains empty.
When I debug,the connection starts successfully, with the given url as a parameter. But my jsonData variable doesn't get printed. Instead the catch block throws the error, stating that there is no data in my variable:
API error: Error Domain=NSCocoaErrorDomain Code=3840 "No value."
Can someone please help me with this?
What am I missing?
Thank you all very much in advance!
[Edited after switching from NSURL Connection to NSURLSession]
Here's an example on how to use NSURLSession with a very convenient "completion handler".
This function contains the network call and has the "completion handler" (a callback for when the data will be available):
func getDataFrom(urlString: String, completion: (data: NSData)->()) {
if let url = NSURL(string: urlString) {
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) { (data, response, error) in
// print(response)
if let data = data {
completion(data: data)
} else {
print(error?.localizedDescription)
}
}
task.resume()
} else {
// URL is invalid
}
}
You can use it like this, inside a new function, with a "trailing closure":
func apiManager() {
getDataFrom("http://headers.jsontest.com") { (data) in
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: [])
if let jsonDict = json as? NSDictionary {
print(jsonDict)
} else {
// JSON data wasn't a dictionary
}
}
catch let error as NSError {
print("API error: \(error.debugDescription)")
}
}
}

Swift NSURLCONNECTION fatal error while parsing json

I am trying to access an api using the following code.
I am getting the error "fatal error: unexpectedly found nil while unwrapping an Optional value" when I am trying to parse json.
I am not sure why is that error happening.
The data is not nil.
var urlFull = NSURL(string: url)!
var urlrequest = NSURLRequest(URL: urlFull)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(urlrequest, queue: queue, completionHandler: {
(response, data, error) -> Void in
println(response)
println(data)
println(error)
if let anError = error {
println(error)
} else {
var jsonError: NSError? = nil
let post = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &jsonError) as NSDictionary
if let aJSONError = jsonError {
println("Error parsing")
} else {
println("The post is: " + post.description)
}
}
})
The problem is your forced cast: as NSDictionary. Whatever's being returned can't be casted to NSDictionary.
You should always use optional casting (as?) and optional unwrapping (if let…) when parsing JSON:
let post = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &jsonError) as? NSDictionary
if let post = post {
// it worked! parse post
} else {
// it's not a dictionary.
println(post)
// see what you have and debug from there
}

XCode 6 UILabel not refreshing text when calling from complition handler

I'm calling to refresh label after refreshQuote() function finishes. When look at the log to see what happened with label.text I can see it has been replaced however the view still looks the same.
Im calling refreshQuote() from viewDidload.
When calling setQuoteLabel directly from viewDidLoad it all works fine
Please help, loosing hope now.
Thanks in advance
func refreshQuote()
{
var url : String = "https://api.parse.com/1/classes/Quotes"
var request : NSMutableURLRequest = NSMutableURLRequest()
request.addValue("------", forHTTPHeaderField: "X-Parse-Application-Id")
request.addValue("------strong text", forHTTPHeaderField: "X-Parse-REST-API-Key")
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
NSLog(error.debugDescription);
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil)
{
var allResults: NSArray = jsonResult["results"] as NSArray
var pickedResult: NSDictionary = allResults[0] as NSDictionary
let q:String = pickedResult["message"] as String!
self.setQuoteLabel(q);
} else
{
// couldn't load JSON, look at error
}
})
}
func setQuoteLabel (quote:String)
{
NSLog(quote)
quoteLabel.text = quote;
quoteLabel.setNeedsDisplay();
NSLog(quoteLabel.text!)
}
All UI components must be updated from the main thread, whereas in your case you are updating most likely from a different thread, because the code is in an asynchronous block.
To force a block of code to be executed in the main thread, you can use dispatch_async as follows:
dispatch_async (dispatch_get_main_queue ()) {
self.setQuoteLabel(q)
}

Resources