How to check the null condition for JSON response? - ios

I am trying to check the null condition for one of the dictionaries of json response.But when i checking the condition, I am getting an error like "Binary operator '==' cannot be applied to operands of type '[String : Any]' and 'JSON'".I am getting this error at the line of if !(chattt == JSON.null).If any one helps me to solve this,would be great.Thanks in advance.
let acce:String = UserDefaults.standard.string(forKey: "access-tokenn")!
print(acce)
let headers:HTTPHeaders = ["Authorization":"Bearer \(acce)","Content-Type":"application/X-Access-Token"]
print((Constants.Chatlistsearch)+(idd))
Alamofire.request((Constants.Chatlistsearch+idd), method: .get, encoding: URLEncoding.default, headers: headers).responseJSON { response in
switch response.result {
case .success:
//print(response)
if response.result.value != nil{
var maindictionary = NSDictionary()
maindictionary = response.result.value as! NSDictionary
// print(maindictionary)
var chat:Dictionary = maindictionary.value(forKey: "data") as! [String:Any]
// print(chat)
var chatt:Dictionary = chat["user"] as! [String:Any]
// print(chatt)
var chattt:Dictionary = chat["chat"] as! [String:Any]
print(chattt)
if !(chattt == JSON.null) {
let viewc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "ChatViewController") as? ChatViewController
self.navigationController?.pushViewController(viewc!, animated: true)
}else{
print("Find Action")
}
// self.data = [String(stringInterpolationSegment: chatt["unique_id"])]
// print(self.data)
}
break
case .failure(let error):
print(error)
}
}
}

You can do it this way
if let chattt = chat["chat"] as? [String:Any] {
//It's available. Execute further tasks
} else {
//It's nil or chat["chat"] type is not dictionary.
}
You can either do it using guard.
guard let chattt = chat["chat"] as? [String:Any] else {
//Using this, the further code will never execute as implemented force return here
return
}
if any issue please let me know.

do the following
guard let chattt = chat["chat"] as? [String:Any] else {
let viewc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "ChatViewController") as? ChatViewController
self.navigationController?.pushViewController(viewc!, animated: true)
return
}

Related

How to retrieve uid according to that PhoneNumber while registration in swift

I have registerButton and otpButton for successful registration to the app.
in registerButton tapping i am sending otp to that registered phonenumber. after otp verification in otpButton then the person successfully registered and i will get uid .
now i want to check if user is already registered or not while registration.. for that i have saved uid in otpButton.. and retrieving uid in registerButton to check if uid is not nil then to show alert message... but here all the time including new user also i am getting recently registered person uid WHY?
How to check if user is already registered or not with their phone number.
saving uid in otpButton:
do{
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
print("the json of otppppppppp \(json)")
DispatchQueue.main.async {
if (self.otpTextField.text == String(self.otpField ?? 12)){
print("registration successfullllll...")
let mobileNum = json["mobile_number"] as! [String : Any]
self.regUid = mobileNum["id"] as? String
print("otp uid \(String(describing: self.regUid))")
DispatchQueue.main.async {
KeychainWrapper.standard.set(self.regUid!, forKey: "regUid")
}
print("the otp uid keywrap \(KeychainWrapper.standard.set(self.regUid!, forKey: "regUid"))")
let loginVC = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.present(loginVC, animated: true)
}
}
}
retrieving uid to check if user is already registered or not
do{
let userId: String? = KeychainWrapper.standard.string(forKey: "regUid")
print("reg userid \(userId)")
if userId != nil{
DispatchQueue.main.async {
AlertFun.ShowAlert(title: "Title", message: "user exist", in: self)
}
}
else{
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
print("the json regggggggggggis \(json)")
let phNum = json["mobile_number"] as? Int
let status = json["status"] as? String
self.otpField = json["otp"] as? Int
}
}
Please help me to check if user exist or not while registration according to uid.
used mobile number instead of regUid as a key chain key
do{
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
print("the json of otppppppppp \(json)")
DispatchQueue.main.async {
if (self.otpTextField.text == String(self.otpField ?? 12)){
print("registration successfullllll...")
let mobileNum = json["mobile_number"] as! [String : Any]
self.regUid = mobileNum["id"] as? String
print("otp uid \(String(describing: self.regUid))")
DispatchQueue.main.async {
KeychainWrapper.standard.set(self.regUid!, forKey: mobileNum)
}
print("the otp uid keywrap \(KeychainWrapper.standard.set(self.regUid!, forKey: mobileNum))")
let loginVC = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.present(loginVC, animated: true)
}
}
}
let mobileNumber = "" // set mobile number
do{
let userId: String? = KeychainWrapper.standard.string(forKey: mobileNumber)
print("reg userid \(userId)")
if userId != nil{
DispatchQueue.main.async {
AlertFun.ShowAlert(title: "Title", message: "user exist", in: self)
}
}
else{
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
print("the json regggggggggggis \(json)")
let phNum = json["mobile_number"] as? Int
let status = json["status"] as? String
self.otpField = json["otp"] as? Int
}
}

How to fix the speed of calling storyboard in swift code when make a if condition in API?

I have an API that check if username and password are correct when correct come back with value "1" CHK ="1" and when calling and check the value I print console with message , message comes fast when I click it comes but switch to the Home storyboard it takes time and sometimes it's not working.
if let url = urlString {
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
print(error)
} else {
if let unwrappedData = data {
do{
//let dataString = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)!
let json = try JSONSerialization.jsonObject(with: unwrappedData, options: []) as AnyObject
if let JsonDic = json[0] as? NSDictionary
{
if let check = JsonDic["CHK"] {
if let check1 = check as? String {
if check1 == "1" {
let HomeViewControler = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
self.navigationController?.pushViewController(HomeViewControler, animated: true)
self.dismiss(animated: false, completion: nil)
print("You Are ready to login")
}else{
print("You Enterd a wrong password or Mail")
}
}
}
}
}catch{
print("There are an Error")
}
Remove self.dismiss(animated: false, completion: nil) and update code in
if check1 == "1"
{
let HomeViewControler = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
self.navigationController?.pushViewController(HomeViewControler, animated: true)
print("You Are ready to login")
}

Loop through an optional object in Swift 4

I have this code
let dic = snapshot.value as! [String:[String:Any]]
Array(dic.values).forEach {
print($0["fcmToken"])
}
It produce these 3
Optional(c1DdtdDF1Rs:APA91bGJBUD65nidQiFDO90AVNgq0wiMjUaZmZXVJ8c_tYmFe5dkmgweOdO10jzPRlMVZF_qNyWMMsu7EhA5IMVo3jLWvBThDteR7WWUPqau-ZFAHKQPHgI5Vb48vA-_4nwkZCKrOVoT)
Optional(c1DdtdDF1Rs:APA91bGJBUD65nidQiFDO90AVNgq0wiMjUaZmZXVJ8c_tYmFe5dkmgweOdO10jzPRlMVZF_qNyWMMsu7EhA5IMVo3jLWvBThDteR7WWUPqau-ZFAHKQPHgI5Vb48vA-_4nwkZCKrOVoT)
Optional(c1DdtdDF1Rs:APA91bGJBUD65nidQiFDO90AVNgq0wiMjUaZmZXVJ8c_tYmFe5dkmgweOdO10jzPRlMVZF_qNyWMMsu7EhA5IMVo3jLWvBThDteR7WWUPqau-ZFAHKQPHgI5Vb48vA-_4nwkZCKrOVoT)
I want to loop through them and add a simple if-check.
I tried
let dic = snapshot.value as! [String:[String:Any]]
Array(dic.values).forEach {
print($0["fcmToken"])
if($0["fcmToken"] != fcmToken) {
print("token is not match detected")
}
}
I kept getting
Binary operator '!=' cannot be applied to operands of type 'Any?' and 'String?'
How would one go about debugging this further?
You have:
let dic = snapshot.value as! [String:[String:Any]]
Array(dic.values).forEach {
print($0["fcmToken"])
if($0["fcmToken"] != fcmToken) {
print("token is not match detected")
}
}
But it’s giving you a compile error.
Assuming that this line is working:
let dic = snapshot.value as! [String:[String:Any]]
I'd write the rest like this:
for v in dic.values {
if let token = v["fcmtoken"] as? String, token != fcmtoken {
print("token \(token) is not match detected")
}
}
The effect is the same and there’s no error.
You can try
let dic = snapshot.value as! [String:[String:Any]]
let tokens = Array(dic.values).map { $0["fcmToken"] as! String }
let exists = tokens.contains(fcmToken)
Your problem as $0["fcmToken"] is of type Any? that can't compared with type String? ( fcmToken )
let dic = snapshot.value as! [String:[String:Any]]
Array(dic.values).forEach {
print($0["fcmToken"])
if let token = $0["fcmToken"] as? String , token != fcmToken {
print("token is not match detected")
}
// or
if ($0["fcmToken"] as? String) != fcmToken {
print("token is not match detected")
}
}
You can savely use
guard let dic = snapshot.value as? [String: [String:Any]] else {
return
}
but it won't function when the value is nil

Can't go from a view to another after doing some instructions

I have this implementation in a part of my app:
Why when I click on "cerca per ISBN" button it goes to the tableView without doing the instructions that I have written?
This is the code of the "cerca per ISBN" button that I click:
#IBAction func ISBNButtonClick(_ sender: Any) {
let libro = Libro.text! as String
if Libro.text!.isEmpty {
//Alert per segnalare i campi mancanti, oltre a caselle rosse
var myAlert = UIAlertController(title:"Attenzione\n", message:"Inserire il codice ISBN", preferredStyle:UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.default){ action in }
myAlert.addAction(okAction);
self.present(myAlert, animated:true, completion:nil);
// placeholder rosso se la text è vuota
Libro.attributedPlaceholder = NSAttributedString(string:"Digita qui...", attributes: [NSForegroundColorAttributeName: UIColor.red])
//se tutti i campi obbligatori sono stati inseriti, proseguo ad altri controlli
}else{
if(isNumeric(string: libro)){
if((libro.characters.count) < 13 || (libro.characters.count) > 13){
//Alert per segnalare l'ISBN più corto di 13 numeri
var myAlert = UIAlertController(title:"Attenzione\n", message:"L'ISBN deve essere di 13 cifre", preferredStyle:UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.default){ action in }
myAlert.addAction(okAction);
self.present(myAlert, animated:true, completion:nil);
}else{
//inviare dati al server
let myUrl = NSURL(string:"http://chuadiv.ddns.net/easytoschool/fetch_book_detailed.php");
let request = NSMutableURLRequest(url:myUrl as! URL);
request.httpMethod = "POST";
let postString = "name=\(libro)&mail=\(UserDefaults.standard.object(forKey: "userEmail") as? String)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
if error != nil{
print("error=\(error)")
return
}
var err: NSError?
do{
var json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray
if let parseJSON: NSArray = json{
for index in 0...parseJSON.count-1 {
print("ciao")
let libro = parseJSON[index] as! [String:Any]
print("\n\n",index,":\n")
let book = resultCell.init(bookId: libro["id"] as! String,bookName: libro["name"] as! String,bookAuthor: libro["author"] as! String,bookSchool: libro["school"] as! String,bookPrice: libro["price"] as! String,bookStatus: libro["status"] as! String,bookISBN: libro["isbn"] as! String,bookType: libro["type"] as! String,bookIdSeller: libro["idSeller"] as! String,bookNameSeller: libro["nameSeller"] as! String,bookSurnameSeller: libro["surnameSeller"] as! String)
book.printBook();
HomeViewController.booksArray.append(book)
}
}
}catch{
print("error=\(error)")
return
}
}
task.resume();
performSegue(withIdentifier: "homeToListBook", sender: self)
}
}else{
var myAlert = UIAlertController(title:"Attenzione\n", message:"Inserire solo numeri per la ricerca attraverso codice ISBN", preferredStyle:UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.default){ action in }
myAlert.addAction(okAction);
self.present(myAlert, animated:true, completion:nil);
}
}
}
I want that when I press the button it sets my array and after it goes to the tableView, but I can't
The issue is that completion block of dataTask will call async so it will call later and you are currently performing segue outside the completion block of it. So what you need to do is call performSegue inside the completion block of dataTask also on Main thread. Also use URL and URLRequest instead of NSURL and NS(Mutable)URLRequest
let myUrl = URL(string:"http://chuadiv.ddns.net/easytoschool/fetch_book_detailed.php")
let request = URLRequest(url:myUrl!)
request.httpMethod = "POST";
let postString = "name=\(libro)&mail=\(UserDefaults.standard.string(forKey: "userEmail")!)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
if error != nil{
print("error=\(error)")
return
}
var err: NSError?
do{
var json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [[String:Any]]
if let parseJSON = json {
for libro in in parseJSON {
let book = resultCell.init(bookId: libro["id"] as! String,bookName: libro["name"] as! String,bookAuthor: libro["author"] as! String,bookSchool: libro["school"] as! String,bookPrice: libro["price"] as! String,bookStatus: libro["status"] as! String,bookISBN: libro["isbn"] as! String,bookType: libro["type"] as! String,bookIdSeller: libro["idSeller"] as! String,bookNameSeller: libro["nameSeller"] as! String,bookSurnameSeller: libro["surnameSeller"] as! String)
book.printBook();
HomeViewController.booksArray.append(book)
}
//Perform segue now
DispatchQueue.main.async {
performSegue(withIdentifier: "homeToListBook", sender: self)
}
}
}catch{
print("error=\(error)")
return
}
}
task.resume()
Note: In Swift use Swift native type array and dictionary instead of NSArray and NSDictionary.
you are appending items to an array of another instance, or even to some static var instead of passing it
what you should do is create class of Book with all properties
class Book {
let id: String
init(data: [String:Any]) {
self.id = data["id"] as? String ?? "" //or some other error handling
}
}
then create an array of books inside current UIViewController
var books: [Book] = []
then do something like
let book = Book(data: libro)
books.append(book)
to pass data you should create an array of books inside destination controller (HomeViewController)
set its DataSource and Delegate functions to create UITableViewCells using this array
and pass data like
override func prepare(for segue: UIStoryboardSegue, sender _: Any?) {
if segue.identifier == "homeToListBook" {
if let destinationVC = segue.destination as? HomeViewController {
destinationVC.books = self.books
}
}
}
EDIT:
and as Nirav D mentioned, segue should be called in main thread after data has been parsed, did not notice this

Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(500))

I am receiving unacceptablStatusCode error everytime I call this function
Alamofire 4.0.0, Swift 3, Xcode 8.
If I pass acceptableStatusCode range to 200...<500, it still gives the same error.
Do I have any error in the function because previous two API's work fine or is it a alamofire 4.0.0 bug???
func getTargetbyDistributor()
{
DispatchQueue.main.async {
SwiftLoader.show("Loading...", animated: true)
}
var param: [String: Any] = [String: Any]()
param = ["user_id":(UserDefaults.standard.object(forKey: "UserInformation") as! NSDictionary).value(forKey: "user_id"),"country_id":(UserDefaults.standard.object(forKey: "UserInformation") as! NSDictionary).value(forKey: "country_id"),"role_id":(UserDefaults.standard.object(forKey: "UserInformation") as! NSDictionary).value(forKey: "role_id"),"from_month_data":txtdate.text!,
"to_month_data":txtToDate.text!]
Alamofire.request(kUrlConstant + "getTargetbyDistributor", method: .post , parameters: param)
.validate()
.responseJSON { response in
switch response.result {
case .success(_):
DispatchQueue.main.async {
SwiftLoader.hide()
}
let str = NSString(data: response.data!, encoding:String.Encoding.utf8.rawValue)
var jsonResult = [String:AnyObject]()
do
{
jsonResult = try JSONSerialization.jsonObject(with: response.data!, options: []) as! [String:AnyObject]
print(jsonResult)
if jsonResult["status"] as! Int == 1
{
print(jsonResult)
self.txtdate.text = ""
self.txtToDate.text = ""
self.bgScrollView.isHidden = false
self.btnNext.isHidden = false
self.PaginationView.isHidden = false
self.btnPrev.isHidden = false
self.bgScrollView.bounces = false
self.bgScrollView.bouncesZoom = false
let hight = CGFloat(((jsonResult["data"] as! NSArray).count * 40) + 50)
self.bgScrollView.frame = CGRect(x: self.bgScrollView.frame.origin.x,y: self.bgScrollView.frame.origin.y,width: self.bgScrollView.frame.size.width,height: hight)
self.PaginationView.frame = CGRect(x: self.PaginationView.frame.origin.x,y: self.bgScrollView.frame.origin.y + self.bgScrollView.frame.size.height + 6,width: self.PaginationView.frame.size.width,height: self.PaginationView.frame.size.height)
if (((jsonResult["data"] as! NSDictionary).object(forKey: "target_data") as! NSDictionary).object(forKey: "month_data") as! NSArray).count >= 1
{
self.headerArray = (((jsonResult["data"] as! NSDictionary).object(forKey: "target_data") as! NSDictionary).object(forKey: "month_data") as! NSMutableArray)
}
if (((jsonResult["data"] as! NSDictionary).object(forKey: "target_data") as! NSDictionary).object(forKey: "data") as! NSArray).count >= 1
{
self.dataTableArray = (((jsonResult["data"] as! NSDictionary).object(forKey: "target_data") as! NSDictionary).object(forKey: "data") as! NSMutableArray)
}
self.header()
self.tblView.reloadData()
}
else
{
let alertController = UIAlertController(title: "Alert", message: jsonResult["message"] as? String, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in
return false;
}
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion:nil)
}
} catch let error as NSError {
print(str);
print(error)
DispatchQueue.main.async {
SwiftLoader.hide()
}
}
print("Validation Successful")
case .failure(let error):
print(error)
DispatchQueue.main.async {
SwiftLoader.hide()
}
}
}
}

Resources