How to pass two values in URL body in JSON swift? - json

I am trying to add parameters in URL body like below
func getUserProfile() {
let deviceId: String = "HardcodeDEVICEIDforiTaag"//(UIDevice.current.identifierForVendor?.uuidString)!
let personalId: String = UserDefaults.standard.string(forKey: "USERID") ?? ""
let headers = ["deviceid": deviceId,"userType": "personal","key": personalId]
let string = "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/getprofile/"
var urlComponents = URLComponents(string: string)
let requestedUserType = URLQueryItem(name: "requestedUserType", value: "personal")
let requestedItem = URLQueryItem(name: "requestedKey", value: personalId)
urlComponents?.queryItems = [requestedItem, requestedUserType]
let urlStr = urlComponents?.url
print(urlStr?.absoluteString)
let request = NSMutableURLRequest(url: NSURL(string:urlStr)! as URL,cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers as! [String : String]
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if error == nil {
let httpResponse = response as? HTTPURLResponse
if httpResponse!.statusCode == 200 {
do {
let jsonObject = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String :AnyObject]
self.userModel = ProfileModel.init(fromDictionary: jsonObject)
print("profile json \(jsonObject)")
print("profile personalid 2222\(personalId)")
if (self.userModel?.userId) != nil {
DispatchQueue.main.async {
self.updateUserDetails()
self.addressTableview.reloadData()
}
} else { DispatchQueue.main.async { Constants.showAlertView(alertViewTitle: "", Message: "No user data found", on: self)}}
} catch { print(error.localizedDescription) }
} else {
//Constants.showAlertView(alertViewTitle: "", Message: "Something went wrong, Please try again", on: self)
}
}
})
dataTask.resume()
}
then got error:
Cannot convert value of type 'URL?' to expected argument type 'String'
i got above error when i am trying to add url to request.
Please help me to solve this error.

This how one should create a url with different components:
let string = "http://itaag-env-1-south-1.elasticbeanstalk.com/getprofile"
var urlComponents = URLComponents(string: string)
let requestedItem = URLQueryItem(name: "requestedKey", value: "yourReqKey")
let requestedUserType = URLQueryItem(name: "requestedUserType", value: "personal")
urlComponents?.queryItems = [requestedItem, requestedUserType]
let url = urlComponents?.url
print(url?.absoluteString)
Edit: Finally use this code to get your request :-
let request = NSMutableURLRequest(url: url!, cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)

Related

how to make HTTPRequest with json in swift

I am making an ios application. I am new to swift and not able to understand my code. can anyone please help me to understand what is going on with my code.
This is login application on adding email id if the email exist it should go to next view controller and if not then it should give error. I am getting difficulty in understanding my code .
Here is my code:
class checkLoginViewController: UIViewController {
#IBOutlet weak var checkUsernametextfield: UITextField!
#IBAction func checkUsernameButton(_ sender: UIButton) {
print("Clicked On SUbmit !!!!")
//Read Value from Text
let email = checkUsernametextfield.text
let myUrl = URL(string: "http://192.168.0.117/rest/signup.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
let postString = "email=\(String(describing: email))";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(String(describing: error))")
return
}
// You can print out response object
print("response = \(String(describing: response))")
//Let's convert response sent from a server side script to a NSDictionary object:
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
// Now we can access value of First Name by its key
let emailValue = parseJSON["email"] as? String
print("email: \(String(describing: emailValue))")
}
} catch {
print(error)
}
}
task.resume()
Output:
Clicked On SUbmit !!!! response = Optional( { URL: http://192.168.0.117/rest/signup.php } { Status
Code: 200, Headers {
Connection = (
"Keep-Alive"
);
"Content-Length" = (
61
);
"Content-Type" = (
"application/json"
);
Date = (
"Mon, 12 Mar 2018 06:35:58 GMT"
);
"Keep-Alive" = (
"timeout=5, max=100"
);
Server = (
"Apache/2.4.27 (Ubuntu)"
); } }) email: nil
Maybe try this. Hope it works.
let url = URL(string:"http://192.168.0.117/rest/signup.php")
let parameters = ["email": checkUsernametextfield.text]
var request = URLRequest(url : url!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject:parameters, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
session.dataTask(with: request, completionHandler: { (data, response, error) in
if let data = data {
do {
let json = try? JSONSerialization.jsonObject(with: data, options: []) as! Dictionary<String, Any>
if let json = json {
print("HERE SHOULD BE YOUR JSON \(json)")
}
}
} else {
print("Error \(String(describing: error?.localizedDescription))")
}
}).resume()
Here is way to send request.
enter code here
static func downloadConfig(url:URL, completion:#escaping (_ sucess:Bool , _ jsonObject: [String: String]?)->() ) {
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded",
forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "id=13&name=Jack"
request.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data,response,error) in
if let data = data ,let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200 {
do {
if let todoJSON = try JSONSerialization.jsonObject(with: data, options: []) as? [String: String]{
completion(true,todoJSON)
}
else
{
completion(false,nil)
}
}
catch {
//erro parsing
completion(false,nil)
}
}
else
{
completion(false,nil)
}
}.resume()
}
use this download json function in this way.
//Download Json File
let base_url = "base_url"
let urlstr = String.init(format: "%#", base_url)
let url = URL(string: urlstr)
GameUtil.downloadConfig(url: url!) {
(sucess: Bool , jsonObject: [String:String]?) in
if sucess , jsonObject != nil
{
self.configJson = jsonObject!
}
}

Passing JSON data from HTTP request to another view controller in Swift 3

How to pass the JSON data from HTTP request to another view controller in swift 3? This function is when selected a cell, It will get the JSON data from server then I have to pass the JSON data to another view controller.
func retrieveTime(jobDateValue: String) -> Void {
if let crew = user!["crew"] as? [String:Any], let crewID = crew["crew_id"] as? String{
let param = ["action": "retrieve time", "job": ["crew_id": crewID, "jobDate": jobDateValue]] as [String : Any]
let headers = [
"content-type": "application/json",
"cache-control": "no-cache"
]
if let postData = (try? JSONSerialization.data(withJSONObject: param, options: [])) {
let request = NSMutableURLRequest(url: URL(string: "http://52.221.231.3/gv/app_api.php")!,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
_ = URLSession.shared
let task = URLSession.shared.dataTask(with: request as URLRequest) {
(data, response, error) -> Void in
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [.mutableContainers])) as? NSDictionary
{
let result = json["result"] as? String
if (result == "success") {
let passValue = json
}else{
}
}
})
}
task.resume()
}
}
}
passing json data to second view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SecondVCSegue"{
if let destination = segue.destination as? SecondVC {
destination.passedData = json
}
}
}
JSON Output:
{
jobs = (
{
jobDate = "2017-09-01";
jobEndTime = 1504231200;
jobID = 88;
jobTime = 1504224000;
}
);
message = "Retrieve Sucessfully";
result = success;
}
You should set up a manual segue in Storyboard, that you only call inside the completion handler of your network request. If the segue is connected to a single tableview cell, it will be called by the system before your async function would finish execution. Once you changed your segue to be manual and not connected to a static table view cell, you can call it using the function performSegue.
func retrieveTime(jobDateValue: String) -> Void {
if let crew = user!["crew"] as? [String:Any], let crewID = crew["crew_id"] as? String{
let param = ["action": "retrieve time", "job": ["crew_id": crewID, "jobDate": jobDateValue]] as [String : Any]
let headers = [ "content-type": "application/json", "cache-control": "no-cache" ]
if let postData = (try? JSONSerialization.data(withJSONObject: param, options: [])) {
var request = URLRequest(url: URL(string: "http://52.221.231.3/gv/app_api.php")!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { (data, response, error) -> Void in
guard error == nil, let data = data else {return}
DispatchQueue.main.async{
if let json = (try? JSONSerialization.jsonObject(with: data)) as? [String:Any]{
let result = json["result"] as? String
if (result == "success") {
let passValue = json
self.performSegue(withIdentifier: "YourSegue", sender: json)
} else{
}
}
}
}
task.resume()
}
}
}
Also use native Swift objects when available instead of their Foundation counterparts (such as NSDictionary, NSMutableURLRequest).
You should also use the sender option of performSegue to send the json data to your other view controller instead of storing it in another variable unless you use the json object in your first view controller as well.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SecondVCSegue"{
if let destination = segue.destination as? SecondVC, let json = sender as? [String:Any] {
destination.passedData = json
}
}
}

response Data is nil

I am getting response data nil.
func fetchSinglePageData() {
var response: NSData?
var errors: NSError?
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
response = NSData(contentsOfFile:"url...?project_id=(self.projectID)&project_page=Request", options: NSDataReadingOptions(0), error: &errors)
print("LatestURL Single page:(response)")
if response == nil {
var alertview = UIAlertView(title: "Network Error", message: "Data not received due to network connection.Try again...", delegate: self, cancelButtonTitle: "Ok")
alertview.show()
}
else{
let jsonDict: NSDictionary = NSJSONSerialization.JSONObjectWithData(response!, options: nil, error: &errors) as NSDictionary
print("JSON Response Single page:(jsonDict)")
var statuses = [NSObject : AnyObject]()
self.lblstartTime?.text = jsonDict["start_time"] as? String
self.lblcurrentStage?.text = jsonDict["current_stage"] as? String
self.lblcompletionTime?.text = jsonDict["completion_time"] as? String
self.lblManager?.text = jsonDict["manager"] as? String
}
})
}
project_id is string which is recevied from presvious page which is correctly working.
In swift 3
//make a url request
let urlString = "your_url"
let urlRequest = URLRequest.init(url: URL.init(string: urlString)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 50)
//create a session
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, urlResponse, error) in
if error != nil{
//handle error
return
}else{
if let responseData = data{
let jsonDict = try JSONSerialization.jsonObject(with: responseData, options: [])as? [String:Any]
//handle your response here
}
}
}
task.resume()
In swift 2.2
let urlString = "your_url"
let request = NSURLRequest(URL: NSURL(string: urlString)!, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 50)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) in
if error != nil{
//handel error
print(error!.localizedDescription)
return
}
if let responseData = data{
do{
if let jsonDict = try NSJSONSerialization.JSONObjectWithData(responseData, options: [])as? [String:Any]{
//you have data in json dict
}
}catch{
print("error in parsing response")
return
}
}
}
task.resume()
func singlePageData(){
var errors: NSError?
let urlString = "xyz.com"
print("URL RESPONSE \(urlString)")
let request = NSURLRequest(URL: NSURL(string: urlString), cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 50)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) in
if error != nil{
//handel error
print(error!.localizedDescription)
var alertview = UIAlertView(title: "Network Error", message: "Data not received due to network connection.Try again...", delegate: self, cancelButtonTitle: "Ok")
alertview.show()
return
}
if let responseData = data{
var jsonDict: NSDictionary = NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.MutableContainers, error: &errors) as NSDictionary!
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
println("Json dict value \(jsonDict)")
self.lblprojectName?.text = jsonDict["name"] as? String
println("lblprojectName: \(self.lblprojectName?.text)")
self.lblstartTime?.text = jsonDict["start_time"] as? String
println("lblstartTime : \(self.lblstartTime?.text)")
self.lblcurrentStage?.text = jsonDict["current_stage"] as? String
println("lblcurrentStage : \(self.lblcurrentStage?.text)")
self.lblcompletionTime?.text = jsonDict["completion_time"] as? String
println("lblcompletionTime : \(self.lblcompletionTime?.text)")
self.lblManager?.text = jsonDict["manager"] as? String
})
}
}
task.resume()
}
This is my answer as per Jitendra Solanki answer i have made changes to code and it is now working in Swift 1.2
After a quick look, maybe \ missing:
NSData(contentsOfFile:"url...?project_id=\(self.projectID)&project_page=Request"
In this line:
response = NSData(contentsOfFile:"url...?project_id=(self.projectID)&project_page=Request", options: NSDataReadingOptions(0), error: &errors)
you have project_id=(self.projectID), to use interpolation you should instead have project_id=\(self.projectID)
I would suggest that you separate the code to generate your full URL, then print the URL to the console and ensure that it is what you would expect.
Then you can visit the url yourself and check to see what the server returns, then once you know you have the correct URL and response you can then work to deserialise the response
EDIT: updated with URLSession (Swift 3 version)
let defaultSession = URLSession(configuration: URLSessionConfiguration.default)
var dataTask: URLSessionDataTask?
let projectID = 12
let url = URL(string: "http://phpyouth.com/clients/halfpricedgrannyflats/app/app_response.php?project_id=\(projectID)&project_page=Request")
dataTask = defaultSession.dataTask(with: url!) {
data, response, error in
if let error = error {
print(error.localizedDescription)
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
if let responseData = data {
if let json = try? JSONSerialization.jsonObject(with: responseData, options: .allowFragments) as? [String:AnyObject] {
print(json)
}
}
}
}
}
dataTask?.resume()

JSON parse error: The data couldn’t be read because it isn’t in the correct format

I am new to Xcode and Swift and have the below code that shows error on print(parseJSON).
Error: The data couldn’t be read because it isn’t in the correct
format.
The code is posting data correctly to the server, but the response cannot be parsed.
JSON response from my ASMX page:
{"status":"Success","message":"User is registered"}
Any help will be appreciated.
// Send data to server side
let myURL = NSURL(string: "http://www.examle.com/Info.asmx/Testing")
let request = NSMutableURLRequest(URL: myURL!)
request.HTTPMethod = "POST"
let postString = "Email=\(userEmail!)&Password=\(userPassword!)"
print(postString)
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?
do{
if let parseJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary{
print(parseJSON) // ERROR HERE
let resultValue = parseJSON["status"] as? String
print("result: \(resultValue)")
var isUserRegistered:Bool = false
if (resultValue == "Success") {
isUserRegistered = true
}
var messageToDisplay:String = parseJSON["message"] as! String!
if (!isUserRegistered){
messageToDisplay = parseJSON["message"] as! String!
}
dispatch_async(dispatch_get_main_queue(), {
let myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default){ action in
self.dismissViewControllerAnimated(true, completion: nil)
}
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
})
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()

Swift 2.0 HTTPS request timed out

After updating to Swift 2.0 my http request is no longer working. I switched url strings from http to https after updating server to ssl due to new swift 2.0 guidelines but now I am getting request timed out. Any help appreciated.
func getJSON(){
activityIndicator.startAnimating()
let myUrl = NSURL(string: "https://www.example.com/getList.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
let userEmail = defaults.objectForKey("email") as? String
let postString = "email=\(userEmail!)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue = parseJSON["status"] as? String
print("result: \(resultValue)")
if(resultValue == "success")
{
self.activityIndicator.stopAnimating()
dispatch_async(dispatch_get_main_queue(), {
self.tableData = parseJSON["bList"] as! NSArray
self.tableFeatData = parseJSON["fList"] as! NSArray
let now = NSDate()
let updateString = "Last Updated at " + self.dateFormatter.stringFromDate(now)
self.refreshControl.attributedTitle = NSAttributedString(string: updateString)
if self.refreshControl.refreshing
{
self.refreshControl.endRefreshing()
}
self.tblView!.reloadData()
})
}
else
{
self.activityIndicator.stopAnimating()
let messageToDisplay = parseJSON["message"] as! String!;
dispatch_async(dispatch_get_main_queue(), {
//Display alert message with confirmation
let myAlert = UIAlertController(title:"Alert", message:messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.Default){action in
self.dismissViewControllerAnimated(true, completion:nil);
}
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated:true, completion:nil);
});
}
}
}
task.resume();
}