I have a JSON Post authentication to make a login request, of course I need to send the user & password parameters to receive a response for filling my HomeViewController, so I need first to validate the two parameters, and if the user doesn't exist of course I'm going to send an Alert and forbid the access to the Home. The thing is that I don't know in which method do I have to put this validation, because the way I'm doing it throws me an alert before the validation. This is my code:
class LoginViewController: UIViewController, LoginProtocol {
#IBOutlet weak var username: UITextField!
#IBOutlet weak var password: UITextField!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
var user : String = ""
var psw : String = ""
var idResponse : String = ""
var message : String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func validateLogin(_ sender: Any) {
DoLogin(self.username.text!, self.password.text!)
}
#IBAction func login(_ sender: Any) {
if self.idResponse != "0" {
validation(message: self.message)
} else {
let vc = self.storyboard!.instantiateViewController(withIdentifier: "home") as! HomeViewController
self.present(vc, animated: false, completion: nil)
vc.getUser = self.username.text!
vc.getPassword = self.password.text!
}
}
func validation(message: String) {
let myAlert = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.alert)
let okAction = UIAlertAction (title: "Ok", style: UIAlertActionStyle.default, handler: nil)
myAlert.addAction(okAction)
self.present(myAlert, animated: true, completion: nil)
return
}
func DoLogin(_ user:String, _ psw:String)
{
let url = URL(string: "http://162.209.99.39:8080/MiClaroBackend/auth")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
self.username.text = user
self.password.text = psw
let paramToSend = ["username":user,"password":psw]
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: paramToSend)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard let _:Data = data else
{
return
}
let json:AnyObject?
do {
json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json{
let loginModel = LoginModel()
let defaultServiceResponse = parseJSON["defaultServiceResponse"] as! NSDictionary
loginModel.message = defaultServiceResponse["message"] as! String
loginModel.idResponse = defaultServiceResponse["idResponse"] as! Int
self.idResponse = String(loginModel.idResponse)
self.message = loginModel.message
print(json!)
}
} catch {
let error = ErrorModel()
error.phrase = "PARSER_ERROR"
error.code = -1
error.desc = "Parser error in login action"
}
})
task.resume()
}
The validateLogin method is attached to a TextView with the action: "EditingDidEnd". So what I need is that when I finish writing the password, the DoLogin function validates that exists and let me continue to the HomeViewController, but the issue is that when I click the button 'Ingresar'(Login), it shows a blank Alert first and only the second time I click the button it let me through immediately. I don't know why is sending the Alert that I declare at the "func validation" if I'm not calling it before. I'm going to attach a picture to show you the Alert that is appearing:
Chances are your EditingDidEnd method calls DoLogin which is processing in background when you press the Login button. hence your if condition below becomes true as your idResponse is initialized to "" empty string.
if self.idResponse != "0"
Rectify this if condition to check if its empty then dont call the validation message.
The best way to do this is to call your DoLogin only after click of the Login button and if in case you have success redirect to Home page. Otherwise show the alert. Please note do the UI action on the main thread.
First Update the Code And User Like this
func DoLogin(_ user:String, _ psw:String)
{
let url = URL(string: "http://162.209.99.39:8080/MiClaroBackend/auth")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let paramToSend = ["username":user,"password":psw]
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: paramToSend)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard let _:Data = data else
{
return
}
let json:AnyObject?
do {
json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json{
let loginModel = LoginModel()
let defaultServiceResponse = parseJSON["defaultServiceResponse"] as! NSDictionary
loginModel.message = defaultServiceResponse["message"] as! String
loginModel.idResponse = defaultServiceResponse["idResponse"] as! Int
self.idResponse = String(loginModel.idResponse)
self.message = loginModel.message
if self.idResponse != "0" {
validation(message: self.message)
} else {
let vc = self.storyboard!.instantiateViewController(withIdentifier: "home") as! HomeViewController
self.present(vc, animated: false, completion: nil)
vc.getUser = user!
vc.getPassword = psw!
}
}
} catch {
let error = ErrorModel()
error.phrase = "PARSER_ERROR"
error.code = -1
error.desc = "Parser error in login action"
}
})
task.resume()
}
If You want to add alert in imageview use this code
var imageView = UIImageView(frame: CGRectMake(220, 10, 40, 40))
imageView.image = yourImage
alert.view.addSubview(imageView)
Related
I am able login, but don't get any data from listpeserta. I want to get user's name etc
func onlinecheckin(){
self.password.resignFirstResponder()
let password1 = password.text;
if let user1 = user.text {
// To trim the characters to remove the empty space
let username = user1.trimmingCharacters(in: CharacterSet.whitespaces)
let passwordnya = password1!.trimmingCharacters(in: CharacterSet.whitespaces)
//Send user data to server side
let myUrl = URL(string: "https://url/jgcm/login.php")!
var request = URLRequest(url: myUrl)
request.httpMethod = "POST"
let postString = "user=\(username) & password=\(passwordnya)"
request.httpBody = postString.data(using: String.Encoding.utf8)
task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
print("response online checking =\(String(describing: response))")
if error != nil {
task.cancel() // To cancel uploading the task.
self.AlertMessage("Error. Please press Login button again.");
print("error=\(String(describing: error))")
return
}
if let datadownload = data {
resultlogin = NSString(data: datadownload, encoding: String.Encoding.utf8.rawValue)!.replacingOccurrences(of: " ", with: "");
print("result of online checking:\(resultlogin)")
}
DispatchQueue.main.async(execute: { () -> Void in
if resultlogin.contains("already") {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "menu")
self.present(secondViewController!,animated: true,completion: nil)
} else {
self.AlertMessage("User atau Password Salah");
}
})
}
task.resume()
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let datapesertac = segue.destination as? datapeserta , let user = sender as? listpeserta{
datapesertac.coba = user
}
}
data peserta controller
var coba : listpeserta?
namalogin.text = coba?.nama
it does not display anything, just show nil
I am showing all address in firstVC Tableview from JSON.. the same addresses i am showing in secondVC tableview here i have an option edit.. so if i click editBtn i am able to send the address to nextVC map.. in nextVC if i continue i am going to finalVC then here i am getting address, here the edited address i need to show in the same row where i click editBtn.. how to do that?
like below i am sending address to nextVC: when i click editBtn in Tableview like below i am sending address to nextVC(which i want to edit)
func btnEditTapped(cell: EditAddressTableViewCell) {
if let indexPath = self.addeditTableview.indexPath(for: cell){
print("edit button address index \(indexPath.row)")
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "AddressViewController") as! AddressViewController
viewController.isEdit = true
var addrLo = addressArray[indexPath.row]
print("in edit total mode address \(addrLo.pincode)")
viewController.editPincode = addrLo.pincode
viewController.editStree = addrLo.streetName
viewController.editColony = addrLo.colony
viewController.editCity = addrLo.city
self.navigationController?.pushViewController(viewController, animated: true)
}
}
this is finalVC. code: here if i push to FirstViewController then the row should be edited with new address but i am here adding one more.. edit is not working for me
func editAddressService(){
let locations: [String: Any] = ["longitude": logitude as Any,"latitude": latitude as Any]
let parameters: [String: Any] = [
"pincode": zipName,
"city": localityName,
"streetName": sublocalityName,
"colony": "",
"location" : locations,
"addressName" : addressTextfield.text
]
let string = "http://jcksdjfksdljfklsdl"
var urlComponents = URLComponents(string: string)
let saveAddrsID: String = addAddrsID ?? ""
print("didload saved address userde edit service \(saveAddrsID)")
let requestedUserType = URLQueryItem(name: "requestedUserType", value: "personal")
let requestedItem = URLQueryItem(name: "addressType", value: "Other")
let requestedItemAddr = URLQueryItem(name: "addressId", value: saveAddrsID)
print("edit addressid \(requestedItemAddr)")
let jsonData = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)
let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String
print(jsonString)
urlComponents?.queryItems = [requestedItem, requestedUserType, requestedItemAddr]
let urlStr = urlComponents?.url
let request = NSMutableURLRequest(url: urlStr!, cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
let postData = String(format: "addressdetails=%#",jsonString) .data(using: .utf8)
request.httpBody = postData
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: Any]
self.editAddrsID = jsonObject["addressId"] as? String
DispatchQueue.main.async {
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
self.navigationController?.pushViewController(viewController, animated: true)
}
} catch { print(error.localizedDescription) }
} else {
}
}
})
dataTask.resume()
}
to know flow i have added only this post related code in github: https://github.com/SwiftSamples/AddressEdit
in my github project flow will be: (profileVC showing all address from JSON) add/edit btn - > (addeditVC showing same profileVC address), editBtn - > profileAddressVC Map continueBtn - > ZoomMapVC(picked address need to show in edit btn index row in profile&addeditVC)
please help me with code to edit address.
for edit and add: this is the difference in /saveaddress/ API
save indexPath from secondVC
pass it to finalVC
get the cell already in finalVC using the saved indexPath
sorting and number of cells must of course be the same in secondVC and finalVC
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)
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!
}
}
I stored my user JSON data on "user" when I login. How can I change the value when i click save button?something like : crew_preferred_name to "Xiao Pang".
UserDefaults.standard.set(json, forKey: "json")
user = UserDefaults().value(forKey: "json")as? NSDictionary
This is JSON Output
}
crew ={
"crew_avatar" = "http://ec2-52-221-231-3.ap-southeast-1.compute.amazonaws.com/gv/images/profile_image/Pang_Kang_Ming_916210_0e9.jpg";
"crew_contact" = 0123456789;
"crew_email" = "pang#xover.com.my";
"crew_gender" = Male;
"crew_id" = PP000001;
"crew_name" = "Pang Kang Ming";
"crew_preferred_name" = PKM;
"crew_qrcode" = "images/qrcode/qrcode_085960293a5378a64bec6ebfa3c89bb7.png"; }
message = "Login Sucessfully";
result = success;
}
This is the button code, I'm posting the action to php but don't know how to change or save the changes in "user" data. Without the code i have to login again to see the new update.
#IBAction func saveBtn(_ sender: Any) {
let preferName = preferNameEditLabel.text!;
if let crew = user!["crew"] as? [String:Any], let crewID = crew["crew_id"] as? String, let crewEmail = crew["crew_email"] as? String, let crewContact = crew["crew_contact"] as? String {
let param = ["action": "update profile", "crew": ["crew_id": crewID, "crew_preferred_name": preferName, "crew_email": crewEmail, "crew_contact": crewContact]] 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
if preferNameEditLabel.text != ""{
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") {
print(result!)
self.view.endEditing(true)
let alert = UIAlertController(title: "Updated", message: "Update Successfully", preferredStyle: UIAlertControllerStyle.alert)
let okButton = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
}else{
let alert = UIAlertController(title: "Error", message: "Update Failed", preferredStyle: UIAlertControllerStyle.alert)
let okButton = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
print(result!)
}
}
})
}
task.resume()
}else{
let alert = UIAlertController(title: "Error", message: "Empty!", preferredStyle: UIAlertControllerStyle.alert)
let okButton = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
}
}
}
}
Don't use NSDictionary in Swift, use its native Swift counterpart, Dictionary.
Then you can access and change a value associated with a known key like this (you will need to make sure that the type of json is [String:Any] before saving it to UserDefaults for this code to work):
UserDefaults.standard.set(json, forKey: "json")
user = UserDefaults().value(forKey: "json") as! [String:Any]
user["crew_name] = "Pang Kang Feng"
simply write this line after getting the latest data
UserDefaults.standard.set(json, forKey: "json")
In this way your "json" key will contain latest data and you can get it as
user = UserDefaults().value(forKey: "json")as? NSDictionary