Send Nested JSON With POST Request iOS Swift 3 - ios

I want to send JSON to Server with POST request but i did not understand how i do this. I select friends from table view and show these friends in my Collection view. And the selected peoples shows in collection views and their email are sent in JSON to Create group. Here is my code written in Swift.
#IBAction func createGroupButton(_ sender: Any) {
let groupName = groupNameTextField.text
let adminEmail = UserDefaults.standard.value(forKey: "userEmail")
if groupName == "" {
alertMessage(msg: "Enter Group name")
}
else if base64String == nil {
alertMessage(msg: "Select Group Image")
}
else if emailArray.isEmpty {
alertMessage(msg: "Select atleast one person")
}
else {
if isNetAvailable {
var emailData: String?
print("email data \(emailArray)")
for i in emailArray {
emailData = "\"email\":\"\(i)\""
}
let postData = "\"name\":\"\(groupName!)\",\"adminemail\":\"\(adminEmail!)\",\"image\":\"\(base64String!)\",\"emailArray\":\"\(emailData!)\""
let postDat = "jsondata={\(postData)}"
print("Post Data \(postDat)")
let urlString = create_group
let url = URL(string: urlString)
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.httpBody = postDat.data(using: String.Encoding.utf8)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
print("Something wrong with creating Group")
}
if data == nil {
print("Nil Data")
}
if response == nil {
print("Nil Response")
}
if response != nil {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Response String is \(responseString)")
}
}
task.resume()
}
else {
alertMessage(msg: "Internet Not Available")
}
}
}
Here is my API
<?php
if($_SERVER["REQUEST_METHOD"] !="POST"){ exit; }
require_once 'dbcon.php';
if (!empty($_POST['jsondata']))
{
$configjson = $_POST['jsondata'];
$config = json_decode($configjson, true);
$groupname = $config['name'];
$adminemail = $config['adminemail'];
$image = $config['image'];
$queryemailcheck = "SELECT * FROM groups_name WHERE admin = '$adminemail' AND groupname = '$groupname'";
$selectquery = mysqli_query($connect, $queryemailcheck);
$totalemails= mysqli_num_rows($selectquery);
if($totalemails>0)
{
echo "Already exist";
}
else {
$queryinsert= "INSERT INTO groups_name(admin , groupname , pic ) VALUES('$adminemail' ,'$groupname' , '$image')";
if(mysqli_query($connect, $queryinsert)){
echo "Successfully Saved";
}else{
echo "Error: " ;
}
$members = $config['emailArray'];
foreach($members as $row ){
$email = $row['email'];
$queryinsert2= "INSERT INTO group_members(groupname , member , status ) VALUES('$groupname' ,'$email' , '0')";
if(mysqli_query($connect, $queryinsert2)){
echo "Successfully Saved";
}else{
echo "Error: " ;
}
}
}
}
else echo "post data is empty";
?>

You can use Alamofire library for handling your webservices. like
Alamofire.request(logoutUrl, method: .post, parameters: dict, encoding: JSONEncoding.default, headers:["Authorization":"Bearer \(accessToken)", "Accept":"application/json", "Content-Type":"application/json; charset=UTF-8"]).responseJSON { (response) in
let json:JSON = JSON(response.result.value)
let status = json["status"].stringValue
let statusCode = response.response?.statusCode

Create network handler class where you can hit webservices from all of your app.
func makeHttpPostRequest(uri:String, postBody:Dictionary<String, Any> ,Completion:#escaping (_ response: AnyObject, _ success: Bool) -> Void) {
let networkCheck = self.getNetworkStatus()
if networkCheck == false {
Completion("NO internet connection." as AnyObject,false)
return
}//end network check block
var urlRequest = self.makeHttpRequestWithUrl(url: uri)
urlRequest.httpMethod = "POST"
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
urlRequest.setValue("application/json", forHTTPHeaderField: "Accept")
//check and set authorization header
if (UserDefaults.standard.object(forKey: AppConstant.KAppAuthenticationToken) != nil) {
let authToken = UserDefaults.standard.object(forKey: AppConstant.KAppAuthenticationToken) as! String
urlRequest.setValue("Token token="+authToken, forHTTPHeaderField: "Authorization")
}
//let postData = [self.addDefultParameters(detailDict: postBody)]
let jsonData = try? JSONSerialization.data(withJSONObject: postBody)
urlRequest.httpBody = jsonData
//create connection
self.httpConnectionWithRequest(request: urlRequest, Completion: Completion)
}
func makeHttpRequestWithUrl(url: String) -> URLRequest {
let urlString = AppConstant.baseUrl+url
let networkUrlRequest = URLRequest.init(url: URL.init(string: urlString)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 50)
return networkUrlRequest
}
func httpConnectionWithRequest(request: URLRequest, Completion:#escaping (_ response: AnyObject, _ success: Bool) -> Void) {
let session = URLSession.shared
// make the request
let task = session.dataTask(with: request) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error is: " + String.init(format: "%#", error?.localizedDescription as! CVarArg))
Completion(error!.localizedDescription as String as AnyObject, false)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
Completion("didn't get response data" as String as AnyObject, false)
return
}
let responseString = String.init(data: responseData, encoding: .utf8)
// parse the result as JSON, since that's what the API provides
if let resp = response as? HTTPURLResponse{
if (UserDefaults.standard.object(forKey: AppConstant.KAppAuthenticationToken) != nil) {
if resp.statusCode == 401{
//auth token expired
self.makeRequestWithNewToken(request: request, Completion: Completion)
}
}
//check if response is Array or dictionary
var jsonArray:[Any]?
var jsonDict:[String:Any]?
// response is in array
do{
jsonArray = try JSONSerialization.jsonObject(with: responseData, options: [])as? [Any]
}catch{
print("response doesn't contain array")
}
//response is in dictionary
do{
jsonDict = try JSONSerialization.jsonObject(with: responseData, options: [])as? [String:Any]
}catch{
print("response doesn't contain dict")
}
//=====
// if resp.statusCode == 200{
if jsonArray != nil{
Completion(jsonArray! as AnyObject, true)
return
}
if jsonDict != nil{
Completion(jsonDict! as AnyObject, true)
return
}
Completion("didn't get response data" as String as AnyObject, false)
return
}
}
task.resume()
}
And through the completion handler you will get the fetched data.

Related

How to get JSON response data from shared class to ViewController?

I'm not using Alamofire, so i want to use JSON post approach in SharedClass and i want to send my api name and all parameters to that function. Finally i want to get the response back. I tried but it's not working. If it's not correct please correct me or if any other options are available please suggest me.
My code in SharedClass
func postRequestFunction(apiName:String , parameters:String ) -> [String:Any] {
var localURL = "hostname/public/index.php/v/***?"
localURL = localURL.replacingOccurrences(of: "***", with: apiName)
var request = URLRequest(url: URL(string: localURL)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print("shared URL : \(request)")
request.httpBody = parameters.data(using: .utf8)
var returnRes:[String:Any] = [:]
let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error
print(error!)
// print("error=\(String(describing: error))")
print("localizedDescription : \(String(describing: error?.localizedDescription))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
do {
returnRes = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
print(returnRes)
} catch let error as NSError {
print(error)
}
}
task.resume()
return returnRes
}
In my view controller class my code is. Here i'm calling function
func getProjectDetails() {
let response = SharedClass.sharedInstance.postRequestFunction(apiName: "API Name", parameters: parameters)
print(response)
let res = response["Response"] as! [String:Any]
let status = res["status"] as! String
if status == "SUCCESS" {
//I will handle response here
} else {
let message = res["message"] as! String
//Call alert function
SharedClass.sharedInstance.alert(view: self, title: "", message: message)
}
}
Here is my solution:
class APIManager {
private init () {}
static let shared = APIManager()
func postRequestFunction(apiName: String , parameters: String, onCompletion: #escaping (_ success: Bool, _ error: Error?, _ result: [String: Any]?)->()) {
var localURL = "hostname/public/index.php/v/***?"
localURL = localURL.replacingOccurrences(of: "***", with: apiName)
var request = URLRequest(url: URL(string: localURL)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print("shared URL : \(request)")
request.httpBody = parameters.data(using: .utf8)
var returnRes:[String:Any] = [:]
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
onCompletion(false, error, nil)
} else {
guard let data = data else {
onCompletion(false, error, nil)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 200 {
do {
returnRes = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
onCompletion(true, nil, returnRes)
} catch let error as NSError {
onCompletion(false, error, nil)
}
} else {
onCompletion(false, error, nil)
}
}
}
task.resume()
}
}
func getProjectDetails() {
/* Notes:
** onCompletion Block Parameters:
success - This indicates whether the API called successfully or not.
error - This indicates errors from either API calling failed, JSON parsing, or httpStatus is not 200.
result - This indicates the JSON parsed result.
** APIManager:
I have renamed your SharedClass to APIManager for better readibility.
** sharedInstance:
I have renamed sharedInstance to shared for better readibility.
*/
APIManager.shared.postRequestFunction(apiName: "API Name", parameters: "parameters") { (success, error, result) in
if success {
if let res = result?["Response"] as? [String: Any] {
if let status = res["status"] as? String {
if status == "SUCCESS" {
//You can handle response here.
} else {
let message = res["message"] as! String
//Call alert function.
}
}
}
} else {
print(error?.localizedDescription)
}
}
}
You forgot the asynchronous paradigm of Service, You can return your API response in Closure, as like below
func postRequestFunction(apiName:String , parameters:String, returnRes: #escaping ([String: Any]) -> () ) {
var localURL = "hostname/public/index.php/v/***?"
localURL = localURL.replacingOccurrences(of: "***", with: apiName)
var request = URLRequest(url: URL(string: localURL)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print("shared URL : \(request)")
request.httpBody = parameters.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else {
// check for fundamental networking error
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
do {
if let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any] {
returnRes(response)
}
} catch let error as NSError {
print(error)
}
}
task.resume()
}
And use like below
postRequestFunction(apiName: "yourUrl", parameters: "Param") { (response) in
print(response)
}

How to reload new data to UITable when one row data is deleted or updated in swift IOS?

So for I've a UITableView in which I'm showing comments which is fetch from my localhost DB, when a user post comment it's send to localhost and store there and it the same time I reload table and the comment is shown it the time but when a user delete a comment or update a comment then in the DB data is actually deleted or updated but my tableview is not reloading with new data till I close the view and open it again.
following is my code.
This my delete comment code:
#objc func deleteComment(){
ProgressHUD.show("Wait Deleting", interaction: false)
customView.removeFromSuperview()
var commentArray : Dictionary<String, Any> = [:]
commentArray["commentId"] = self.getCommentId
let myUrl = URL(string: "http://127.0.0.1:8000/api/comment/delete");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
request.addValue("application/json", forHTTPHeaderField: "Content-type")
guard let httpbody = try? JSONSerialization.data(withJSONObject: commentArray, options: []) else { return }
request.httpBody = httpbody
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(error)")
return
}
// print out response object
// print("response = \(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 {
if parseJSON["delete"] != nil{
ProgressHUD.dismiss()
self.alertDeleted()
}else {
if parseJSON["error"] != nil{
ProgressHUD.dismiss()
print(parseJSON["error"] as Any)
}
}
}
} catch {
print(error)
}
}
task.resume()
}
This is delete comment alert.
public func alertDeleted(){
let alertController = UIAlertController(title: "Comment Deleted:", message: "Press Ok to continue.", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Ok", style: .default) { (_) in
self.showMatchCommentsApiCall()
}
alertController.addAction(confirmAction)
self.present(alertController, animated: true, completion: nil)
}
This is update comment code.
#objc func updateComment(){
ProgressHUD.show("Wait Upating", interaction: false)
updateCommentView.removeFromSuperview()
var commentArray : Dictionary<String, Any> = [:]
commentArray["commentId"] = self.getCommentId
commentArray["updatedComment"] = textView.text
let myUrl = URL(string: "http://127.0.0.1:8000/api/comment/update");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
request.addValue("application/json", forHTTPHeaderField: "Content-type")
guard let httpbody = try? JSONSerialization.data(withJSONObject: commentArray, options: []) else { return }
request.httpBody = httpbody
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(error)")
return
}
// print out response object
//print("response = \(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 {
if parseJSON["update"] != nil{
ProgressHUD.dismiss()
self.alertCommentUpdated()
self.showMatchCommentsApiCall()
return
}else {
if parseJSON["error"] != nil{
ProgressHUD.dismiss()
print(parseJSON["error"] as Any)
}
}
}
} catch {
print(error)
}
}
task.resume()
}
My ShowMatchCommentsApiCall() function.
public func showMatchCommentsApiCall(){
ProgressHUD.show("Please Wait", interaction: false)
guard let url = URL(string: "http://127.0.0.1:8000/api/matchComments/\(getMatchId)") else {return}
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let dataResponse = data,
error == nil else {
print(error?.localizedDescription ?? "Response Error")
return }
do{
//here dataResponse received from a network request
let jsonResponse = try JSONSerialization.jsonObject(with:
dataResponse, options: [])
// print(jsonResponse) //Response result
guard let jsonArray = jsonResponse as? [[String: Any]] else {
return
}
//print(jsonArray)
for comments in jsonArray{
guard let commentID = comments["commentId"] as? Int else { return }
guard let userID = comments["userId"] as? Int else { return }
guard let userName = comments["userName"] as? String else { return }
let userImgUrl = comments["userImg"] as? String
if userImgUrl != nil{
self.commentsUserImgUrl.append(userImgUrl!)
}else {
self.commentsUserImgUrl.append("nil")
}
guard let commentMessage = comments["comment"] as? String else { return }
self.commentId.append(commentID)
self.commmentsUserId.append(userID)
self.commentsUserName.append(userName)
self.comments.append(commentMessage)
}
} catch let parsingError {
print("Error", parsingError)
}
DispatchQueue.main.async {
self.MatchScoreTable.reloadData()
ProgressHUD.dismiss()
}
}
task.resume()
}
STEP 1. :self.commentsArray.remove(at: indexPath.row)
STEP 2. : self.tableView.deleteRows(at:[indexPath],with:UITableViewRowAnimation.automatic)
STEP 3. : self.tableView.reloadData()
After deleting or updating data just call a UITableView method reloadData
Syntax is as follows :
tableView.reloadData()

Using POST request in HTTP method holds the UI?

When I tap on button it will perform a service request operation.Based on the result it will redirect to next view controller.
After loading Next view controller holds or block the UI. How to solve this issue ? I am using RestAPI and GCD first time in swift, so don't know how to solve this.....
This is login button
#IBAction func btnLogin(_ sender: Any)
{
self.api()
}
This is the function what we call.
func api()
{
let myURL = URL(string: "http://www.digi.com/laravel_api_demo/api/demoapipost")
let request = NSMutableURLRequest(url: myURL!)
request.httpMethod = "POST"
let strEmail = tfLgnID.text
let strPwd = tfPwd.text
let postString = ["username":strEmail, "password":strPwd]
//let postString = ["username":"ayush", "password":"abc"]
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
//create the session object
//let session = URLSession.shared
do {
request.httpBody = try JSONSerialization.data(withJSONObject: postString, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body
print("Successfully passed data to server")
} catch let error {
print(error.localizedDescription)
}
let postTask = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print("POST Method :\(json)")
let dict = json as? [String: Any]
let num = dict!["status"]
print("Status : \(num)")
print("Dict : \(dict)")
print("username : \(dict!["username"])")
print("password : \(dict!["password"])")
if dict!["status"] as! Int == 1
{
print("Successfully Logged In")
DispatchQueue.main.async {
let visitorVC = self.storyboard?.instantiateViewController(withIdentifier: "VisitorVC") as! VisitorVC
self.present(visitorVC, animated: true, completion: nil)
}
print("OK")
}
else
{
print("Not OK")
}
// handle json...
}
} catch let error {
print(error.localizedDescription)
}
}
postTask.resume()
}
Try this method
func api() {
var request = URLRequest(url: URL(string: "")!) // put your url
request.httpMethod = "POST"
let strEmail = tfLgnID.text
let strPwd = tfPwd.text
let postString:String = "user_id=\(strEmail)&user_id=\(strPwd)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary {
print(jsonResult)
let status = jsonResult["status"]! as! NSString
print("status\(status)")
DispatchQueue.main.async(execute: {
// your error Alert
})
}
else {
DispatchQueue.main.async(execute: {
let visitorVC = self.storyboard?.instantiateViewController(withIdentifier: "VisitorVC") as! VisitorVC
self.present(visitorVC, animated: true, completion: nil)
})
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
}

How to parse Json and Normal Parmeters with URLSession swift 3

I am passing parameters in parameters And Using below code.
this is ok for this parametere: module = mymoduleName and userId = userId
func callWebServices(url: String, methodName: String, parameters: String,istoken: Bool, tokenval: String, completion: #escaping CompletionHandler){
var url_param = url
if(methodName == "GET" && parameters != "")
{
url_param = url_param + "?" + parameters
}
var request = URLRequest(url: URL(string: url_param)!)
request.httpMethod = methodName
if(methodName == "POST" && parameters != "")
{
let postString = parameters
request.httpBody = postString.data(using: .utf8)
}
if(istoken)
{
request.setValue("Bearer " + tokenval , forHTTPHeaderField: "Authorization")
}
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else {
print("error=\(String(describing: error))")
return
}
if let httpsStatus = response as? HTTPURLResponse, httpsStatus.statusCode != 200 {
print("Status Code should be 200, but it is \(httpsStatus.statusCode)")
print("response = \(String(describing: response))")
}
do {
let dictData = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSDictionary
completion(dictData)
} catch {
print("error is : \(error)")
}
}
task.resume()
}
But i have to parse parameters and json together like
module = mymoduleName
userId = userId and data = [{
"dmode_id": 1,
"user_id": 1,
"schedule_course_id": 1,
"course_id": 1}]
when i am calling this method getting error. help me to fix this issue. I am calling method like this.
callWebServices(url: URLS.Base_URL, methodName: "POST", parameters: param, istoken: false, tokenval: "", completion: { (jsonResult) in
print(jsonResult)
})

How to send form data in POST request in Swift 3

I am trying to post form-data using webservice, userName & password, but in response it's showing an error stating "Could not connect to the server.".
Please help me to send form data in the POST request.
let dict:[String:String] = ["userName": userName as! String, "password": password as! String]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
let url = URL(string: "(some url)")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
print(error!.localizedDescription)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue:String = parseJSON["success"] as! String;
print("result: \(resultValue)")
print(parseJSON)
}
} catch let error as NSError {
print(error)
}
}
task.resume()
} catch {
print(error.localizedDescription)
}
I've tried adding values in the request, may be some values are missing in the request formed. Please help!
Thats the POSTMAN response
my calling api class
class ApiService
{
static func getPostString(params:[String:Any]) -> String
{
var data = [String]()
for(key, value) in params
{
data.append(key + "=\(value)")
}
return data.map { String($0) }.joined(separator: "&")
}
static func callPost(url:URL, params:[String:Any], finish: #escaping ((message:String, data:Data?)) -> Void)
{
var request = URLRequest(url: url)
request.httpMethod = "POST"
let postString = self.getPostString(params: params)
request.httpBody = postString.data(using: .utf8)
var result:(message:String, data:Data?) = (message: "Fail", data: nil)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if(error != nil)
{
result.message = "Fail Error not null : \(error.debugDescription)"
}
else
{
result.message = "Success"
result.data = data
}
finish(result)
}
task.resume()
}
}
and when use it
ApiService.callPost(url: url, params: params, finish: finishPost)
and the finish function
func finishPost (message:String, data:Data?) -> Void
{
do
{
if let jsonData = data
{
let parsedData = try JSONDecoder().decode(Response.self, from: jsonData)
print(parsedData)
}
}
catch
{
print("Parse Error: \(error)")
}
}

Resources