Swift JSON parsing username and password - ios

I am trying to POST username & password as NSDictionary through JSON format. I am getting this following error :
Domain=NSCocoaErrorDomain Code=3840 "
JSON text did not start with array or object and option to allow fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
My code is below:
#IBAction func loginAuthentication(_ sender: UIButton) {
let username : NSString = NameTextField.text! as NSString
let password : NSString = passwordTextField.text! as NSString
let parameters = [
"username": "\(username)",
"password": "\(password)"
]
print(parameters)
let headers = [
"content-type": "application/json",
"cache-control": "no-cache",
"postman-token": "121b2f04-d2a4-72b7-a93f-98e3383f9fa0"
]
if let postData = (try? JSONSerialization.data(withJSONObject: parameters, options: [])) {
let request = NSMutableURLRequest(url: URL(string: "http://..")!,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
print(request.httpBody)
// let session = URLSession.shared
let task = URLSession.shared.dataTask(with: request as URLRequest) {
(data, response, error) -> Void in
if (error != nil) {
print("Error message \(error)")
} else {
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? NSDictionary
{
let success = json["error"] as? Bool
print("Error from php\(success)")
let message = json["message"] as? String
// here you check your success code.
if (success == false)
{
print("Result1 \(message)")
self.performSegue(withIdentifier: "", sender: self)
}
else
{
self.dismiss(animated: true, completion: nil)
print("Result2 \(message)")
}
}
})
}
}
task.resume()
}
}

The problem looks to me like your string is not being serialized correctly. Instead of your current json serialization approach, simply convert a swift dictionary to data.
//Start with a dictionary
let body = [
"username": "bob",
"password": "admin"
]
//Serialize it.... you might want to put this in a do try catch block instead
let jsonBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
//Add it to the request
request.httpBody = jsonBody
//make the request, etc.
let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response, error in

Related

API URL to post json formatted data

How would I transfer code from textfields into json formatted data.
Below is the current code i have, but it doesn't seem to transfer the data within the textfields to json when the button is clicked. Is their any errors within this code?
#IBAction func submitButton(_ sender: Any) {
// parse in paramaters
let parameters = ["Name": nameTextField, "Email": emailTextField, "DOB": dateTextField] as [String : Any]
guard let url = URL(string: "https://prod-69.westeurope.logic.azure.com/workflows/d2ec580e6805459893e498d43f292462/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=zn8yq-Xe3cOCDoRWTiLwDsUDXAwdGSNzxKL5OUHJPxo") else { return }
var request = URLRequest(url: url)
// let url session know that this is a post request
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// convert paramaters to JSON
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else { return }
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
Are nameTextField, emailTextField and dateTextField of type String or UITextField. Make sure you are passing the UITextField.text property and not the UITextField itself.
See below:
guard let name = nameTextField.text,
let email = emailTextField.text,
let dob = dateTextField.text else {
return
}
let parameters: [String: String] = ["name": name, "email": email, "dob": dob]

How to avoid "Error Domain=NSCocoaErrorDomain Code=3840" in Swift?

I keep getting this particular error when trying to parse a JSON response in Swift:
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
Code:
let dict = [
"phone": phone,
"firstname": "\(String(describing: firstName))",
"lastname": "\(String(describing: lastName))"
]
as [String: Any]
if let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: []) {
var request = URLRequest(url: URL(string: "\(config.baseURL)employee")!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
request.timeoutInterval = 30.0
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
DispatchQueue.main.async {
self.alertController.singleButtonAlertController("Error", (error?.localizedDescription)!, self, self.defaultAction)
return
}
}
guard let data_ = data else {
return
}
do {
let jsonObj = try JSONSerialization.jsonObject(with: data_, options: .mutableContainers) as? NSDictionary
guard let parseJSON = jsonObj else {
return
}
self.navigationItem.rightBarButtonItem = self.rightBarButton
let meta = parseJSON["meta"] as? [String:Any]
let status = meta!["status"] as? String
if status == "200" {
isEmployeeModified = true
self.dismiss(animated: true, completion: nil)
} else {
let info = meta!["info"] as? String
let message = meta!["message"] as? String
DispatchQueue.main.async {
self.alertController.singleButtonAlertController(info!, message!, self, self.defaultAction)
}
}
} catch let error as NSError {
print(error)
}
}
task.resume()
I have used similar codes in other parts of the project and everything checks out.
According to this Error, the response from your server is not a valid JSON
Can you use responseString instead of responseJSON like below
Alamofire.request(URL, method: requestMethod, parameters: params).responseString{ response in
print(response)
}
I was able to figure out what was wrong and I'm going to explain this here for future readers. Apparently, I was doing a GET request the wrong way, so when I intend to do a POST request, for some reason, it still sees it as a GET request and that was why I kept getting the response: Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
Below is my refactored code and it works without any hassle:
let dict = [
"phone": phone,
"firstname": firstName,
"lastname": lastName
] as [String : Any]
guard let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: []) else {
return
}
guard let url = URL(string: "\(config.baseURL)employee") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData as Data
request.timeoutInterval = 10
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print("JSON Response: \(response)")
}
if error != nil {
DispatchQueue.main.async {
self.navigationItem.rightBarButtonItem = self.rightBarButton
self.alertController.singleButtonAlertController("Error", (error?.localizedDescription)!, self, self.defaultAction)
return
}
}
if let data = data {
do {
let parseJSON = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary
let meta = parseJSON!["meta"] as? [String:Any]
let status = meta!["status"] as? String
if status == "200" {
isEmployeeModified = true
self.dismiss(animated: true, completion: nil)
} else {
let info = meta!["info"] as? String
let message = meta!["message"] as? String
DispatchQueue.main.async {
self.alertController.singleButtonAlertController(info!, message!, self, self.defaultAction)
}
}
} catch {
print(error)
}
}
}.resume()

post parameter to sever using dictionary swift

I am trying to send data to the server using a dictionary but unfortunately the data is not saving to the database (fields were found to be blank) and I am getting the below response:
Optional(["status": true, "msg": successfull])
And also tried to show UIActivityIndicator to user until he got a response but couldn't find a way.
Code attempted:
let dict = [ "key_one": self.tf1.text!,"key_two":self.tf2.text!]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(dict, options: .PrettyPrinted)
// create post request
let url = NSURL(string: "myAPIUrl.php?")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// insert json data to the request
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = jsonData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in
if error != nil{
print("Error -> \(error)")
return
}
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject]
print("Response -> \(result)")
} catch {
print("Inside Error Section -> \(error)")
}
}
task.resume()
} catch {
print(error)
}
// write this in one fucantion
let Username:NSString = EmailTextField.text! as NSString
let password:NSString = PasswordTextField.text! as NSString
let headers = [
"content-type": "application/json",
"cache-control": "no-cache",
"postman-token": "121b2f04-d2a4-72b7-a93f-98e3383f9fa0"
]
let parameters = [
"username": "\(Username)",
"password": "\(password)"
]
if let postData = (try? JSONSerialization.data(withJSONObject: parameters, options: [])) {
var request = NSMutableURLRequest(url: URL(string: "YOUR_URL_HERE")!,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
let session = URLSession.shared
let task = URLSession.shared.dataTask(with: request as URLRequest) {
(data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? NSDictionary
{
let success = json["status"] as? Int
let message = json["message"] as? String
// here you check your success code.
if (success == 1)
{
print(message)
let vc = UIActivityViewController(activityItems: [image], applicationActivities: [])
present(vc, animated: true)
}
else
{
// print(message)
}
}
})
}
}
task.resume()
}

Not able to login with api calling and not able to save the access id

This is my first application i am working on.I have one api url for login calling function. And when i enter username, password. It will generate one customer id.And i need to save that is, and i have to use that particular id for all my screen till user logged out.
But when i am doing api calling for login . Its not working. Please help me out.
This is my parameter passing :
{
"username" : "u#gmail.com",
"password" : "u123"
}
My json output after login api call :
{
"status": 1,
"message": "Login success.",
"CustomerDetails": {
"CustomerId": "1",
"CustomerName": "u",
"CustomerEmail": "u#gmail.com",
"CustomerMobile": "901",
"CustomerAddress": "#45, 7th main road."
}
}
In this i need to save the CustomerId and i have to use that CustomerId to all my screens.
My api calling fuction while login button tap :
func getcartdetaildata () {
let headers = [
"cache-control": "no-cache",
"postman-token": "4c933910-0da0-b199-257b-28fb0b5a89ec"
]
let jsonObj:Dictionary<String, Any> = [
"username" : "\(UsernameEmail)",
"password" : "\(Password)"
]
if (!JSONSerialization.isValidJSONObject(jsonObj)) {
print("is not a valid json object")
return
}
if let postData = try? JSONSerialization.data(withJSONObject: jsonObj, options: JSONSerialization.WritingOptions.prettyPrinted) {
let request = NSMutableURLRequest(url: NSURL(string: "http://Login.php")! as URL,
cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
///print(error)
} else {
print("123.......... ")
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? Dictionary<String,AnyObject>
{
print(json)
let status = json["status"] as? Int;
if(status == 1)
{
print("asdasdasx.......... ")
// let access_token = json["CustomerId"]
//print(access_token)
DispatchQueue.main.async(execute: {
//
//
// //Set logged in to true
// UserDefaults.standard.set(true, forKey: "ISLOGGEDIN")
//
// //Set access token
// UserDefaults.standard.setValue(access_token, forKey: "CustomerId")
//
// UserDefaults.standard.synchronize()
//
})
}
}
})
}
})
dataTask.resume()
}
}
Please help me out.
Thanks
func apicalling () {
let Username:NSString = EmailTextField.text! as NSString
let password:NSString = PasswordTextField.text! as NSString
let headers = [
"content-type": "application/json",
"cache-control": "no-cache",
"postman-token": "4c933910-0da0-b199-257b-28fb0b5a89ec"
]
let parameters = [
"username": "\(Username)",
"password": "\(password)"
]
do {
let postData = try JSONSerialization.data(withJSONObject: parameters, options :[])
let request = NSMutableURLRequest(url: NSURL(string: "http://Login.php")! as URL,cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
///print(error)
} else {
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? Dictionary<String,AnyObject>
{
let status = json["status"] as? Int;
if(status == 1)
{
print(json)
}
}
})
}
})
dataTask.resume()
} catch {
// print("JSON serialization failed: \(error)")
}
}
Code for save data in NSUserDefaults.
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(YOUR_VALUE, forKey: "PASSKEY")
userDefaults.synchronize() // don't forgot this line
Retriving data from NSUserDefaults
if let VARIABLE = userDefaults.valueForKey("PASSKEY") {
// do something here when a Data exists
}
else {
// no data exists
}

POST w/ JSON Body - Swift3 - fragments?

I'm simply trying to send a JSON string via a Swift3 httprequest.
Tried using a Dictionary, and an escaped string ...
func getToken(successHandler: #escaping (Any) -> Void, errorHandler: #escaping (Any) -> Void) {
var request = URLRequest(url: URL(string: "http://my-api.domain.com/getToken")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do
{
// try with Dictionary
let bodyJson: [String: String] = [
"username": "theusername"
]
let bodyJsonData = try JSONSerialization.data(withJSONObject: bodyJson, options: [])
// try with escaped String
let jsonString = "{" +
"\"username\": \"theusername\"," +
"}"
let jsonStringData = jsonString.data(using: String.Encoding.utf8)
//request.httpBody = bodyJsonData
request.httpBody = jsonStringData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
print(error)
errorHandler(error)
return
}
guard let data = data else {
print("Data is empty")
errorHandler("Data is empty")
return
}
var json: Any? = nil
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
DispatchQueue.main.asyncAfter(deadline: .now()) {
successHandler(json)
}
}
catch let error as NSError {
errorHandler(error)
}
}
task.resume()
}
catch
{
errorHandler(error)
}
}
I keep getting:
Handle Error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did
not start with array or object and option to allow fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array or
object and option to allow fragments not set.}
I can't find how to try allowing fragments, all of the examples/tutorials are for Swift2.x :/
Unsure what to do!
// prepare json data
let mapDict = [ "1":"First", "2":"Second"]
let json = [ "title":"ABC" , "dict": mapDict ] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
// create post request
let endpoint: String = "https://yourAPI"
let session = URLSession.shared
let url = NSURL(string: endpoint)!
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
let task = session.dataTask(with: request as URLRequest){ data,response,error in
if error != nil{
print(error?.localizedDescription)
return
}
}
task.resume()
} catch {
print("bad things happened")
}

Resources