Extra argument error in call [duplicate] - swift2

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
}

Related

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

This application is modifying the autolayout engine from a background thread, which can lead to engine corruption

I am getting this error This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.This will cause an exception in a future release. I don't know what is causing this error. Can anybody help me.
func getUserDataFromTwitterWithUser(user : PFUser)
{
//NRLoader.showLoader()
let strTwURL = "https://api.twitter.com/1.1/users/show.json? screen_name="+PFTwitterUtils.twitter()!.screenName! + "&access_token="+PFTwitterUtils.twitter()!.authToken!
let twURL = NSURL (string: strTwURL)
let request = NSMutableURLRequest(URL: twURL!, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 2.0) as NSMutableURLRequest
PFTwitterUtils.twitter()?.signRequest(request)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if error == nil {
var jsonOptional = Dictionary<String, AnyObject>()
do {
jsonOptional = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers ) as! Dictionary<String, AnyObject>
// use jsonData
} catch {
// report error
}
var userName = ""
if let screenName = jsonOptional["screen_name"] as? String{
userName = screenName
}
else if let name = jsonOptional["name"] as? String{
userName = name
}
var profilePicUrl = ""
if let picUrl = jsonOptional["profile_image_url"] as? String{
profilePicUrl = picUrl
}
AppUser.currentUser()?.username = userName
AppUser.currentUser()?.profileAwsURL = profilePicUrl
//NRLoader.hideLoader()
//if ParseUtils.isLoggedInUserIsAnonymous() {
let signUpVC:SignMeUpViewController = self.storyboard!.instantiateViewControllerWithIdentifier("SignMeUpViewController") as! SignMeUpViewController
signUpVC.isFromLogin = true
self.navigationController!.pushViewController(signUpVC, animated: true)
//} else {
// self.pushToSubmitDreamViewController()
//}
}
else {
//NRLoader.hideLoader()
NRToast.showToastWithMessage(error!.description)
}
}).resume()
}
The dataTaskWithRequest call runs in the background and then calls your completion handler from the same thread. Anything that updates the UI should run on the main thread, so all of your current handler code should be within a dispatch_async back onto the main queue:
dispatch_async(dispatch_get_main_queue()) {
// Do stuff to UI
}
Swift 3:
DispatchQueue.main.async() {
// Do stuff to UI
}
Therefore, ideally all the code you currently have within if error == nil should be off in another function, say called handleRequest, so your current code becomes:
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if error == nil {
dispatch_async(dispatch_get_main_queue(), {
self.handleRequest(...)I
})
}
Swift 3
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if error == nil {
DispatchQueue.main.async {
self.handleRequest(...)I
}
}
Should try Symbolic Breakpoint to detect the issue:-
Then put your UI Update code in main thread
DispatchQueue.main.async {}
You'd better change UI only in the main thread
swift3,
let liveInfoUrl = URL(string: "http://192.168.1.66/api/cloud/app/liveInfo/7777")
let task = URLSession.shared.dataTask(with: liveInfoUrl! as URL) {data, response, error in
guard let data = data, error == nil else { return }
DispatchQueue.main.async {
print(String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) ?? "aaaa")
//do some ui work
}
}
if the above suggestions still give you no joy then the sure-est way is to redesign your functions so that getting what you need with
URLSession.shared.dataTask
then hands over so a variable declared outside that function, then a separate UIControl ( button, swipe etc ) displays it to a label or textview or whatever.
After all that is what the error message is telling you. they're separate concerns

Need help adding name to qrcode so i can save to parse

I cannot figure out why im getting this error.
This is the function to update a guest(Participant). I'm trying to save the Qr code i created to a PFFile and save to parse.
func update() {
_ = LabelText
let query = PFQuery(className: "Participant")
query.getObjectInBackgroundWithId(LabelText) {
(Update: PFObject?, error: NSError?) -> Void in
Update!["firstname"] = self.firstnameTF!.text
Update!["lastname"] = self.lastnameTF!.text
Update!["grade"] = self.gradeTF!.text
Update!["teacher"] = self.teacherTF.text
Update!["email"] = self.emailTF.text
Update!["phone"] = self.phoneTF.text
Update!["transportation"] = self.transportationTF.text
Update!.saveInBackground()
print("updated")
if self.QrImage == nil {
print("Image is Blank")
return
}else{
//Image is not blank
let imageData = UIImageJPEGRepresentation(self.QrImage!, 1)
let parseImageFile = PFFile(data: imageData!)
Update!.setObject(parseImageFile!, forKey: "qrcode")
Update!.saveInBackgroundWithBlock( {
(success: Bool , error: NSError?) -> Void in
})
}
self.dismissViewControllerAnimated(true, completion: {});
}
}
I can see the image in the self.QrImage field and i only get the error on:
let parseImageFile = PFFile(data: imageData!)
Why am i getting a nil error when it should have a value there?
Edit 1:
let imageData = UIImagePNGRepresentation(self.QrImage!)
let parseImageFile = PFFile(data: imageData!)
Update!.setObject(parseImageFile!, forKey: "qrcode")
Update!.saveInBackgroundWithBlock( {
(success: Bool , error: NSError?) -> Void in
})
}
Same result."fatal error: unexpectedly found nil while unwrapping an Optional value"
Edit 2:
So it seems there must be a name value associated with the image before you upload it to parse. My Image is of a Qrcode i create from other data. here's my code:
func displayQrCode() {
print(self.qrdata.text)
let data = self.qrdata.text!.dataUsingEncoding(NSISOLatin1StringEncoding)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter!.setValue(data, forKey: "inputMessage")
filter!.setValue("Q", forKey: "inputCorrectionLevel")
self.qrcodeImage = filter!.outputImage!
let scaleX = qrCode.frame.size.width / qrcodeImage!.extent.size.width
let scaleY = qrCode.frame.size.height / qrcodeImage!.extent.size.height
let transformedImage = qrcodeImage!.imageByApplyingTransform(CGAffineTransformMakeScale(scaleX, scaleY))
self.qrCode.image = UIImage(CIImage: transformedImage)
print("QRCode Made")
}
now i guess i need to add a name to the self.qrCode.image?
This is what needs to be done before you use UIImagePNGRepresentation:
self.QrImage = UIImage(named: "qrcode.png")

Completion handler giving: Type of expression is ambiguous without more context, after updating to swift 2

I'm using the SODA Client for swift (Created by Socrata), I just updated to XCode 7 and swift 2 and found some troubles. The one I haven't been able to solve is the completion handler case when it finds an error, it's not accepting the line "syncCompletion(.Error (reqError))" that supposedly should get the error and return to main thread.
I've seen many errors with the same description here "Type of expression is ambiguous without more context", but not in completion handlers, I saw one using do - catch that is different. I'm don't know enough of swift to find out the way to change this.
Some answers suppose you should rewrite the code because some types could have change in swift 2, but I wouldn't know where to start rewriting.
Thanks in advance for your help.
var task = session.dataTaskWithRequest(request, completionHandler: { data, response, reqError in
// We sync the callback with the main thread to make UI programming easier
let syncCompletion = { res in NSOperationQueue.mainQueue().addOperationWithBlock { completionHandler (res) } }
// Give up if there was a net error
if reqError != nil {
syncCompletion(.Error (reqError))
return
}
// Try to parse the JSON
// println(NSString (data: data, encoding: NSUTF8StringEncoding))
var jsonError: NSError?
var jsonResult: AnyObject!
do {
jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
} catch var error as NSError {
jsonError = error
jsonResult = nil
} catch {
fatalError()
}
if let error = jsonError {
syncCompletion(.Error (error))
return
}
// Interpret the JSON
if let a = jsonResult as? [[String: AnyObject]] {
syncCompletion(.Dataset (a))
}
else if let d = jsonResult as? [String: AnyObject] {
if let e : AnyObject = d["error"] {
if let m : AnyObject = d["message"] {
syncCompletion(.Error (NSError(domain: "SODA", code: 0, userInfo: ["Error": m])))
return
}
}
syncCompletion(.Dataset ([d]))
}
else {
syncCompletion(.Error (NSError(domain: "SODA", code: 0, userInfo: nil)))
}
})
Solved, I replaced:
if reqError != nil
With
if let error = reqError
and:
syncCompletion(.Error (reqError))
with
syncCompletion(.Error (error))

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
}

Resources