Duplicate array items getting appended in Response (Swift) - ios

I am using two APIs, one for fetching the Cars added by the user and the second to (Adding new car) submit the car details into my backend. When I open the View of the car details, all 11 Car details are getting fetched properly.
But when I submit the car details (Add New Car) by clicking the add rounded button and the fetch the details of the added car it shows 22 car added in the frontend Table View but now in the backend of the API.
Here are some screenshots.
Before adding a new car
After adding a new car
Here is the code for the same.
Below function is getting used in Viewdidload to fetch the details:
func responsedatavehicle(){
let emailid = defaults.string(forKey: "email")
var request = URLRequest(url: URL(string: "http://www.example.com/getMyVehicleInfo?email=\(emailid!)")!)
print("Email in resposfunction \(emailid!)")
request.httpMethod = "GET"
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
do{
// let postString = "?mobile="+ph!
print("mobno is inside getdata \(emailid!)")
// //print(postString)
// request.httpBody = postString.data(using: .utf8)
APESuperHUD.show(style: .loadingIndicator(type: .standard), title: nil, message: "Loading...")
//self.activityIndicator("Please Wait")
}catch let error{
//print(error.localizedDescription)
return
}
// self.activityIndicator("Please Wait")
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil
{
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json{
print(parseJSON)
if let mobile = parseJSON["error"] as! Int? {
let msg = parseJSON["message"] as! String?
if (mobile == 0){
//print(userId)
DispatchQueue.main.async {
// self.showGlobalAlertwithMessage(msg as! NSString)
if let heroeArray = json!.value(forKey: "content") as? Array<[String:Any]> {
//looping through all the elements
self.labelArray.append(contentsOf: heroeArray)
}
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview()
//print(self.labelArray.count)
for i in 0..<self.labelArray.count{
if let heroeDict = self.labelArray[i] as? NSDictionary{
// let stationname = heroeDict.value(forKey: "charging_station") as! String
let brandname = heroeDict.value(forKey: "brand_name") as! String
let modelname = heroeDict.value(forKey: "car_name") as! String
let accharger = heroeDict.value(forKey: "ac_charger") as! String
let dccharger = heroeDict.value(forKey: "dc_charger") as! String
let vehiclenumber = heroeDict.value(forKey: "vehicle_registration_number") as! String
let imageurl = heroeDict.value(forKey: "vehicle_photo") as! String
self.brandnamearray.append(brandname)
self.modelnamearray.append(modelname)
self.acchargerarray.append(accharger)
self.dcchargerarray.append(dccharger)
self.imageurlarray.append(imageurl)
self.vehiclenoarray.append(vehiclenumber)
print(self.imageurlarray)
}
}
self.myTableView.reloadWithAnimation()
}
}else {
DispatchQueue.main.async {
//self.showGlobalAlertwithMessage(msg as! NSString)
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview()
}
}
}
}
} else{
print("ERROR IN ALERT")
}
}
catch{
// self.showGlobalAlertwithMessage("Could not successfully perform this request. Please try again later")
}
}
task.resume()
}
Cellforrowat Function
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyVehicleTableViewCell
cell.brandnamecell.text = brandnamearray[indexPath.row]
cell.modelnamecell.text = modelnamearray[indexPath.row]
cell.acchargercell.text = acchargerarray[indexPath.row]
cell.dcchargercell.text = dcchargerarray[indexPath.row]
cell.vehiclenumbercell.text = vehiclenoarray[indexPath.row]
cell.ImageView.sd_setImage(with: URL(string: imageurlarray[indexPath.row]), placeholderImage: UIImage(named: "placeholder.png"))
cell.aclabel.layer.borderColor = UIColor.darkGray.cgColor
cell.aclabel.layer.borderWidth = 1.0
cell.aclabel.layer.cornerRadius = 5
cell.aclabel.layer.masksToBounds = true
cell.dclabel.layer.borderColor = UIColor.darkGray.cgColor
cell.dclabel.layer.cornerRadius = 5
cell.dclabel.layer.masksToBounds = true
cell.dclabel.layer.borderWidth = 1.0
cell.aclabel.layer.shadowColor = UIColor.lightGray.cgColor
cell.aclabel.layer.shadowOpacity = 0.5
cell.aclabel.layer.shadowRadius = 10.0
cell.aclabel.layer.shadowOffset = .zero
cell.aclabel.layer.shadowPath = UIBezierPath(rect: cell.aclabel.bounds).cgPath
cell.aclabel.layer.shouldRasterize = true
cell.dclabel.layer.shadowColor = UIColor.lightGray.cgColor
cell.dclabel.layer.shadowOpacity = 0.5
cell.dclabel.layer.shadowRadius = 10.0
cell.dclabel.layer.shadowOffset = .zero
cell.dclabel.layer.shadowPath = UIBezierPath(rect: cell.dclabel.bounds).cgPath
cell.dclabel.layer.shouldRasterize = true
cell.backview.layer.borderColor = UIColor(red:0.92, green:0.92, blue:0.98, alpha:0.9).cgColor
cell.backview.layer.cornerRadius = 8
cell.backview.layer.masksToBounds = true
cell.backview.layer.borderWidth = 8.0
cell.shadowmodel.layer.cornerRadius = 13.0
cell.shadowmodel.layer.shadowColor = UIColor.lightGray.cgColor
cell.shadowmodel.layer.shadowOpacity = 0.5
cell.shadowmodel.layer.shadowRadius = 10.0
cell.shadowmodel.layer.shadowOffset = .zero
cell.shadowmodel.layer.shadowPath = UIBezierPath(rect: cell.shadowmodel.bounds).cgPath
cell.shadowmodel.layer.shouldRasterize = true
return cell
}
Below function is getting used to add a new car:
func submitcar(){
if vehiclenumberstring == ""{
SCLAlertView().showError("Error", subTitle: "Please enter vehicle number ") // Error
}
else {
let emailsubmit = defaults.string(forKey: "email")
print("email inside submit car is \(emailsubmit!)")
var request = URLRequest(url: URL(string: "http://www.example.com/apimobileapps/addVehicleInfo")!)
request.httpMethod = "POST"
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
do{
let postString = "brand_name="+brandname+"&car_name="+modelname+"&vehicle_registration_number="+vehiclenumberstring+"&email="+emailsubmit!
print(postString)
request.httpBody = postString.data(using: .utf8)
APESuperHUD.show(style: .loadingIndicator(type: .standard), title: nil, message: "Loading...")
// self.activityIndicator("Please Wait")
}catch let error{
//print(error.localizedDescription)
return
}
let task = URLSession.shared.dataTask(with: request){
(data, response, error) in
if (error != nil){
return
}
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json{
//print(parseJSON)
if let userId = parseJSON["error"] as! Int? {
let msg = parseJSON["message"] as! String?
if (userId == 0){
//print(userId)
DispatchQueue.main.async {
// self.showGlobalAlertwithMessage(msg as! NSString)
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true); self.effectView.removeFromSuperview()
}
}
}else {
DispatchQueue.main.async {
// self.showGlobalAlertwithMessage(msg as! NSString)
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview();
}
}
}
}
} else{
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview();
}
}
}catch{
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview();
}
//print(error)
}
}
task.resume()
}
responsedatavehicle()
}
My Array count is showing duplicate values in the table view on submit button action.

Related

how to use codable and decodable for the following json?

I have a following sample json file I want to do it with modal classes but am not sure how to do this in code.
{
"countryCodes": [{
"country_code": "AF",
"country_name": "Afghanistan",
"dialling_code": "+93"
},
{
"country_code": "AL",
"country_name": "Albania",
"dialling_code": "+355"
},
{
"country_code": "DZ",
"country_name": "Algeria",
"dialling_code": "+213"
},
{
"country_code": "AS",
"country_name": "American Samoa",
"dialling_code": "+1"
}
]
}
My modal class is as follows
import Foundation
class CountryModal : NSObject, NSCoding{
var countryCodes : [CountryCode]!
/**
* Instantiate the instance using the passed dictionary values to set the properties values
*/
init(fromDictionary dictionary: [String:Any]){
countryCodes = [CountryCode]()
if let countryCodesArray = dictionary["countryCodes"] as? [[String:Any]]{
for dic in countryCodesArray{
let value = CountryCode(fromDictionary: dic)
countryCodes.append(value)
}
}
}
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if countryCodes != nil{
var dictionaryElements = [[String:Any]]()
for countryCodesElement in countryCodes {
dictionaryElements.append(countryCodesElement.toDictionary())
}
dictionary["countryCodes"] = dictionaryElements
}
return dictionary
}
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
#objc required init(coder aDecoder: NSCoder)
{
countryCodes = aDecoder.decodeObject(forKey: "countryCodes") as? [CountryCode]
}
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
#objc func encode(with aCoder: NSCoder)
{
if countryCodes != nil{
aCoder.encode(countryCodes, forKey: "countryCodes")
}
}
}
and
import Foundation
class CountryCode : NSObject, NSCoding{
var countryCode : String!
var countryName : String!
var diallingCode : String!
/**
* Instantiate the instance using the passed dictionary values to set the properties values
*/
init(fromDictionary dictionary: [String:Any]){
countryCode = dictionary["country_code"] as? String
countryName = dictionary["country_name"] as? String
diallingCode = dictionary["dialling_code"] as? String
}
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if countryCode != nil{
dictionary["country_code"] = countryCode
}
if countryName != nil{
dictionary["country_name"] = countryName
}
if diallingCode != nil{
dictionary["dialling_code"] = diallingCode
}
return dictionary
}
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
#objc required init(coder aDecoder: NSCoder)
{
countryCode = aDecoder.decodeObject(forKey: "country_code") as? String
countryName = aDecoder.decodeObject(forKey: "country_name") as? String
diallingCode = aDecoder.decodeObject(forKey: "dialling_code") as? String
}
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
#objc func encode(with aCoder: NSCoder)
{
if countryCode != nil{
aCoder.encode(countryCode, forKey: "country_code")
}
if countryName != nil{
aCoder.encode(countryName, forKey: "country_name")
}
if diallingCode != nil{
aCoder.encode(diallingCode, forKey: "dialling_code")
}
}
}
How do I use these models to get the value of to say India +91 code? I am new to swift so I am clueless as to how to use these models.
the method I know is simple method of ditionary
fileprivate func loadNames(Country: String ) {
// //var countryCodes : [CountryCode]!
// var dict = [Coordinator]?.self
if let filePath = Bundle.main.path(forResource: "CountryCode", ofType: "json") {
if let jsonData = NSData(contentsOfFile: filePath) {
do {
// countryCodes = try? JSONDecoder().decode(CountryCode.self, from: jsonData as Data)
var countryCodes = try JSONSerialization.jsonObject(with: jsonData as Data, options: []) as? [String: Any]
// let countryCodes = try? JSONDecoder().decode(Welcome.self, from: jsonData as Data)
print ("country d ",countryCodes!)
let countryArray = countryCodes!["countryCodes"] as? NSArray
if countryArray!.count > 0
{
for countryElement in countryArray!
{
let dict = countryElement as! NSDictionary
if (dict["country_code"] as! String).description == countryCodeLocale
{
print("found ",(dict["dialling_code"] as! String ).description)
country_codeText.text = (dict["dialling_code"] as! String ).description
phone_NumberText.text = "99133131602"
return
}
}
}
} catch {
print(error.localizedDescription)
}
}
}
}
func fetchValues()
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
request.returnsObjectsAsFaults = false
do
{
let result = try context.fetch(request)
for data in result as! [NSManagedObject]
{
self.nameArr.append(data.value(forKey: "name") as! String)
self.lastNameArr.append(data.value(forKey: "lastname") as! String)
}
self.tableView.reloadData()
} catch {
print("Failed")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.nameArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? testTVCell
cell?.nameLbl.text = self.nameArr[indexPath.row]
cell?.lastNameLbl.text = self.lastNameArr[indexPath.row]
cell?.deleteBtn.tag = indexPath.row
return cell!
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
#IBAction func deleteAction(_ sender: UIButton) {
// self.nameArr.remove(at: sender.tag)
// self.lastNameArr.remove(at: sender.tag)
// self.tableView.reloadData()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
fetchRequest.returnsObjectsAsFaults = false
let index = sender.tag
do
{
if let result = try? context.fetch(fetchRequest)
{
for object in result as! [NSManagedObject]
{
print(object.value(forKey: "name") as! String)
if ((object).value(forKey: "name") as! String).description == nameArr[index]
{
print(object.value(forKey: "name") as! String)
context.delete(object )
self.lastNameArr.remove(at: index)
self.nameArr.remove(at: index)
DispatchQueue.main.async
{
self.tableView.reloadData()
}
break
}
}
}
}
catch
{
print("error")
}
let _ : NSError! = nil
do {
try context.save()
self.tableView.reloadData()
} catch {
print("error : \(error)")
}
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
print("Deleted")
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
fetchRequest.returnsObjectsAsFaults = false
let index = indexPath.row
do
{
if let result = try? context.fetch(fetchRequest)
{
for object in result as! [NSManagedObject]
{
print(object.value(forKey: "name") as! String)
if ((object).value(forKey: "name") as! String).description == nameArr[index]
{
print(object.value(forKey: "name") as! String)
context.delete(object )
DispatchQueue.main.async
{
}
}
}
}
}
catch
{
print("error")
}
let _ : NSError! = nil
do {
try context.save()
} catch {
print("error : \(error)")
}
self.lastNameArr.remove(at: index)
self.nameArr.remove(at: index)
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
#IBAction func submitTapped(_ sender: Any)
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Testing", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(self.nameTxt.text, forKey: "name")
newUser.setValue(self.lastNameTxt.text, forKey: "lastname")
do
{
try context.save()
}
catch
{
print("Failed saving")
}
}
func apiCall()
{
let urlString = "https://example.org"
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url! as URL)
activityView.startAnimating()
self.view.addSubview(activityView)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in
if error != nil
{
DispatchQueue.main.async
{
let alert = UIAlertController(title: "Network Connection Lost", message: "Please try again", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .cancel, handler: { Void in
self.activityView.stopAnimating()
})
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
}
return
}
do
{
let result = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as AnyObject
print(" JSON : ", result)
let a = result as! NSArray
let b = a[0] as! NSDictionary
print("name ", (b["Name"] as! String).description)
var nameArray = [String]()
for element in a
{
nameArray.append(((element as! NSDictionary)["Name"] as! String).description)
}
print("nameArray ", nameArray)
DispatchQueue.main.async
{
self.activityView.stopAnimating()
self.activityView.isHidden = true
}
}
catch
{
print("Error -> \(error)")
DispatchQueue.main.async
{
self.activityView.stopAnimating()
let alert = UIAlertController(title: "Alert?", message: error as? String,preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
return
}
}
}
task.resume()
}
}
let indexpath = NSIndexPath(row: sender.tag, section: 0)
let cell = tableView.cellForRow(at: indexpath as IndexPath) as? testTVCell
if (self.tableView.isEditing) {
cell?.deleteBtn.setTitle("Edit", for: .normal)
self.tableView.setEditing(false, animated: true)
} else {
cell?.deleteBtn.setTitle("Done", for: .normal)
self.tableView.setEditing(true, animated: true)
}
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let urlString = appDelegate.serverUrl + "queryClassifiedList"
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url! as URL)
let spinner = JHSpinnerView.showDeterminiteSpinnerOnView(self.view)
spinner.progress = 0.0
self.view.addSubview(spinner)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
var dict : [AnyHashable: Any] = [
"channel" : appDelegate.channel,
"device" : appDelegate.deviceId,
"classifiedtype" : self.classifiedType,
"startnum" : startNum,
"endnum" : endNum
]
if UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != nil && UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != -1
{
let categoryRow = (UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int)!
dict["categoryid"] = categoryRow
}
if UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != nil && UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != -1
{
let cityId = (UserDefaults.standard.value(forKey: "cityRowFilter") as? Int)!
dict["city"] = cityId
}
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: dict, options: [])
request.httpBody = jsonData
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let urlString = appDelegate.serverUrl + "queryClassifiedList"
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url! as URL)
let spinner = JHSpinnerView.showDeterminiteSpinnerOnView(self.view)
spinner.progress = 0.0
self.view.addSubview(spinner)
request.httpMethod = "POST"
var bodyData : String!
bodyData = "channel=" + appDelegate.channel + "&device=" + appDelegate.deviceId + "&Classifiedtype=" + self.classifiedType.description + "&Startnum=" + startNum.description + "&Endnum=" + endNum.description
if UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != nil && UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != -1
{
let categoryRow = (UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int)!
bodyData = bodyData + "&Categoryid=" + categoryRow.description
}
if UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != nil && UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != -1
{
let cityId = (UserDefaults.standard.value(forKey: "cityRowFilter") as? Int)!
bodyData = bodyData + "&city=" + cityId.description
}
print("bodyData : ", bodyData)
request.httpBody = bodyData.data(using: String.Encoding.utf8)
}
but I want modal class method implementation. Can someone help?
You can try
struct Root: Codable {
let countryCodes: [CountryCode]
}
struct CountryCode: Codable {
let countryCode, countryName, diallingCode: String
enum CodingKeys: String, CodingKey {
case countryCode = "country_code"
case countryName = "country_name"
case diallingCode = "dialling_code"
}
}
let res = try? JSONDecoder().decode(Root.self,from:jsonData)
print(res.countryCodes)
res.countryCodes.forEach {
if $0.countryCode == "DZ" {
print($0.diallingCode)
}
}

UITableCell value not passing to function within UIViewController Swift 3

I have a table that is populated by a search function. There are two buttons within the cell, a checkmark to say yes to a user and an X to say no. There is an insert function that inserts the selection into the database. Unfortunately the value from the table is not being passed to the insert function. Within the insert function, I'm using guestusername.text which is the name of the label in my cell. I'm getting the error 'Use of unresolved identifier guestusername'. I've tried everything I can think of, code below.
class MyShotsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var guest = [AnyObject]()
var avas = [UIImage]()
var valueToPass:String!
var revieweduser:String!
var age = [AnyObject]()
var city = [AnyObject]()
var state = [AnyObject]()
#IBOutlet var tableView: UITableView!
var cell: MyShotsCell?
var index = 0
override func viewDidLoad() {
super.viewDidLoad()
doSearch("")
}
// cell numb
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return guest.count
}
// cell config
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MyShotsCell
// get one by one user related inf from users var
let guest2 = guest[indexPath.row]
let ava = avas[indexPath.row]
// shortcuts
let guestname = guest2["username"] as? AnyObject
let age = guest2["age"]
let city = guest2["city"] as? String
let state = guest2["state"] as? String
// refer str to cell obj
cell.guestusername.text = guestname as! String
cell.ageLbl.text = (NSString(format: "%#", age as! CVarArg) as String)
cell.cityLbl.text = city
cell.stateLbl.text = state
cell.avaImg.image = ava as? UIImage
return cell
}
// search / retrieve users
public func doSearch(_ guestusername : String) {
// shortcuts
let username = user?["username"] as! String
let url = URL(string: "http://www.xxxxx.com/xxxxx.php")!
var request = URLRequest(url: url) // create request to work with users.php file
request.httpMethod = "POST" // method of passing inf to users.php
let body = "revieweduser=\(username)" // body that passes inf to users.php
request.httpBody = body.data(using: .utf8) // convert str to utf8 str - supports all languages
// launch session
URLSession.shared.dataTask(with: request) { data, response, error in
// getting main queue of proceeding inf to communicate back, in another way it will do it in background
// and user will no see changes :)
DispatchQueue.main.async(execute: {
if error == nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
// clean up
self.guest.removeAll(keepingCapacity: false)
self.avas.removeAll(keepingCapacity: false)
self.tableView.reloadData()
// delcare new secure var to store json
guard let parseJSON = json else {
print("Error while parsing")
return
}
guard let parseUSERS = parseJSON["users"] else {
print(parseJSON["message"] ?? [NSDictionary]())
return
}
self.guest = parseUSERS as! [AnyObject]
print(self.guest)
// for i=0; i < users.count; i++
for i in 0 ..< self.guest.count {
// getting path to ava file of user
let ava = self.guest[i]["ava"] as? String
let revieweduser = self.guest[i]["username"] as? String
let age = (NSString(format: "%#", self.guest[i]["age"] as! CVarArg) as String)
let city = self.guest[i]["city"] as? String
let state = self.guest[i]["state"] as? String
self.tableView.reloadData()
} catch {
DispatchQueue.main.async(execute: {
let message = "\(error)"
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
} else {
DispatchQueue.main.async(execute: {
let message = error!.localizedDescription
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
})
} .resume()
}
// custom body of HTTP request to upload image file
func createBodyWithParams(_ parameters: [String: String]?, boundary: String) -> Data {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
return body as Data
}
func insertShot(_ rating : String) {
self.tableView.reloadData()
let reviewer = user?["username"] as! String
// url path to php file
let url = URL(string: "http://www.xxxxxx.com/xxxxxxx.php")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// param to be passed to php file
let param = [
"user" : reviewer,
"revieweduser" : cell?.guestusername.text,
"rating" : rating
] as [String : Any]
// body
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// ... body
request.httpBody = createBodyWithParams(param as? [String : String], boundary: boundary)
// launch session
URLSession.shared.dataTask(with: request) { data, response, error in
// get main queu to communicate back to user
DispatchQueue.main.async(execute: {
if error == nil {
do {
// json containes $returnArray from php
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
// declare new var to store json inf
guard let parseJSON = json else {
print("Error while parsing")
return
}
// get message from $returnArray["message"]
let message = parseJSON["message"]
//print(message)
// if there is some message - post is made
if message != nil {
// reset UI
// self.msgTxt.text = ""
// switch to another scene
//self.tabBarController?.selectedIndex = 3
_ = self.navigationController?.popViewController(animated: true)
}
} catch {
// get main queue to communicate back to user
DispatchQueue.main.async(execute: {
let message = "\(error)"
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
} else {
// get main queue to communicate back to user
DispatchQueue.main.async(execute: {
let message = error!.localizedDescription
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
})
}.resume()
return
}
#IBAction func yesBtn_clicked(_ sender: UIButton) {
self.insertShot("Yes")
}
#IBAction func noBtn_clicked(_ sender: UIButton) {
self.insertShot("No")
}
}

Reading JSON file with Swift 3

With this code i can show the "result"
var movies: [NSDictionary]?
var dates: NSDictionary?
func fetchNowPlayingMovies(){
let apiKey = "8e3967947a95555f9c430e68d070a0e7"
let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)"+"&language=en-US&page=1")
let request = URLRequest(url: url! as URL, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 10)
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: OperationQueue.main)
let task: URLSessionDataTask = session.dataTask(with:request, completionHandler: {(dataOrNil, reponse, error) in
if let data = dataOrNil{
if let responseDictionary = try! JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
//print("reponse: \(responseDictionary)")
self.movies = responseDictionary["results"] as? [NSDictionary]
self.dates = responseDictionary["dates"] as? NSDictionary
self.tableView.reloadData()
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
task.resume()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MovieCell", for: indexPath) as! MovieTableViewCell
//MARK: - JSON Properties
let movie = movies![indexPath.row]
let date = dates![indexPath.row]
let title = movie["title"] as! String
let vote_average = movie["vote_average"] as! Double
let overview = movie["overview"] as! String
let baseUrl = "http://image.tmdb.org/t/p/w500"
let posterPath = movie["poster_path"] as! String
let imageUrl = URL(string: baseUrl + posterPath)
// Configure the cell...
cell.lblTitle.text = title
cell.lblOverview.text = overview
cell.lblVoteAVG.text = String(vote_average)
cell.imgPosterPath.sd_setImage(with: imageUrl)
return cell
}
Request: https://api.themoviedb.org/3/movie/now_playing?api_key=8e3967947a95555f9c430e68d070a0e7&language=en-US&page=1
How i can get the "page" and the "maximum" in "dates"?
Thank you!
var movies: [NSDictionary]?
var dates: NSDictionary?
var page: Int? // var for page
var maximum: String? // var for maximum in dates
func fetchNowPlayingMovies(){
let apiKey = "8e3967947a95555f9c430e68d070a0e7"
let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)"+"&language=en-US&page=1")
let request = URLRequest(url: url! as URL, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 10)
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: OperationQueue.main)
let task: URLSessionDataTask = session.dataTask(with:request, completionHandler: {(dataOrNil, reponse, error) in
if let data = dataOrNil{
if let responseDictionary = try! JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
//print("reponse: \(responseDictionary)")
self.movies = responseDictionary["results"] as? [NSDictionary]
self.dates = responseDictionary["dates"] as? NSDictionary
// This is how you get to page
print("page: \(responseDictionary["page"]!)")
self.page = responseDictionary["page"] as? Int
print("page: \(self.page!)")
// This is how you get to maximum in dates
self.maximum = self.dates?["maximum"] as? String
print("maximum: \(self.maximum!)")
self.tableView.reloadData()
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
task.resume()
}
I hope it helped

NSURLSession.sharedSession().dataTaskWithRequest runs slow in function

My problem arises when I want to populate data from my mysql database into a class object. I am trying to return an array of objects and it returns nil and then it fills itself somehow. How can I make it fill before returning the blank array?
Here is my code and a screenshot of code output
import Foundation
class Research
{
var mainResearchImageURL:String = ""
var userProfileImageURL:String = ""
var caption:String = ""
var shortDescription:String = ""
init(mainResearchImageURL :String, userProfileImageURL:String, caption:String, shortDescription:String)
{
self.mainResearchImageURL = mainResearchImageURL
self.userProfileImageURL = userProfileImageURL
self.caption = caption
self.shortDescription = shortDescription
}
class func downloadAllResearches()->[Research]
{
var researches = [Research]()
let urlString = "http://localhost/test/index.php"
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
let postString = "action=listresearches"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
if (error == nil) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
//let dictionary = json!.firstObject as? NSDictionary
var counter:Int = 0;
for line in json!{
let researchData = line as! NSDictionary
let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String)
researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor.
counter += 1
print ("counter value \(counter)")
print("array count in loop is = \(researches.count)")
}
}catch let error as NSError{
print(error)
}
} else {
print(error)
}})
task.resume()
print("array count in return is = \(researches.count)")
return researches
}
}
And this is the output:
add this on you completionHandler ( it works if you update a view)
dispatch_async(dispatch_get_main_queue(), {
if (error == nil) { ...... }
})
Advice 1:
return the task and use a completion param in your method,
you can cancel the task if it's too slow.
Advice 2 :
Use alamofire and swiftyJson framework
What happen here is that you are returning the value before finish (remember that the call is Asynchronous), you can make something like this:
class func downloadAllResearches(success:([Research])->Void,failure:(String)->Void)
{
var researches = [Research]()
let urlString = "http://localhost/test/index.php"
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
let postString = "action=listresearches"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
if (error == nil) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
//let dictionary = json!.firstObject as? NSDictionary
var counter:Int = 0;
for line in json!{
let researchData = line as! NSDictionary
let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String)
researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor.
counter += 1
print ("counter value \(counter)")
print("array count in loop is = \(researches.count)")
}
success(researches)
}catch let error as NSError{
print(error)
failure("Can be extract from NSERROR")
}
} else {
print(error)
failure("Error - Can be extract for NSERROR")
}})
task.resume()
}
And for call this Fuction use something like this:
Research.downloadAllResearches({ (objects:[Research]) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//Do whatever you like with the content
})
}) { (failureLiteral:String) -> Void in
}

Swift 2 Function Call and JSON usage

I have a Problem with Swift and Xcode 7.
class ConnectVC: UITableViewController {
var username:Array< String > = Array < String >()
var TableData:Array< String > = Array < String >()
var pictures:Array< String > = Array < String >()
var profile_pictures:Array< String > = Array < String >()
override func viewDidLoad() {
super.viewDidLoad()
get_data_from_url("-url-")
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TableData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ConnectVCCell
let picture = pictures[indexPath.row]
print(pictures.count)
print(picture)
print(profile_pictures.count)
let pic = profile_pictures[indexPath.row]
if picture != "" {
let aString = "-url-"
let url = NSURL(string: aString)
let data = NSData(contentsOfURL: url!)
print(url)
let image = UIImage(data: data!)
cell.imageURL.image = image
}else{
print("No picture")
cell.imageURL.image = nil
}
cell.mainLabel.text = TableData[indexPath.row]
return cell
}
func get_data_from_url(url:String)
{
let url = NSURL(string: url)
let urlRequest = NSMutableURLRequest(URL: url!,
cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 15.0)
let queue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(
urlRequest,
queue: queue,
completionHandler: {response, data, error in
if data!.length > 0 && error == nil{
let json = NSString(data: data!, encoding: NSASCIIStringEncoding)
self.extract_json(json!)
}else if data!.length == 0 && error == nil{
print("Nothing was downloaded")
} else if error != nil{
print("Error happened = \(error)")
}
}
)
}
func extract_json(data:NSString)
{
let jsonData:NSData = data.dataUsingEncoding(NSASCIIStringEncoding)!
do {
// Try parsing some valid JSON
let json: AnyObject? = try NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments)
let data_list = json as? NSArray
for (var i = 0; i < data_list!.count ; i++ )
{
if let data_obj = data_list![i] as? NSDictionary
{
if let text = data_obj["text"] as? String
{
if let picture = data_obj["picture"] as? String
{
if let user = data_obj["user"] as? String
{
self.save_image("-url-")
TableData.append(text + " [" + user + "]")
pictures.append(picture)
}
}
}
}
}
}
catch let error as NSError {
// Catch fires here, with an NSErrro being thrown from the JSONObjectWithData method
print("A JSON parsing error occurred, here are the details:\n \(error)")
}
do_table_refresh();
}
func save_image(url:String){
let url = NSURL(string: url)
let urlRequest = NSMutableURLRequest(URL: url!,
cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 15.0)
let queue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(
urlRequest,
queue: queue,
completionHandler: {response, data, error in
if data!.length > 0 && error == nil{
let json = NSString(data: data!, encoding: NSASCIIStringEncoding)
self.extract_json_picture(json!)
}else if data!.length == 0 && error == nil{
print("Nothing was downloaded")
} else if error != nil{
print("Error happened = \(error)")
}
}
)
}
func extract_json_picture(data:NSString)
{
let jsonData:NSData = data.dataUsingEncoding(NSASCIIStringEncoding)!
do {
// Try parsing some valid JSON
let json: AnyObject? = try NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments)
print(json)
let user_info = json as? NSArray
if let user_list = user_info![0] as? NSDictionary
{
if let profile_picture = user_list["picture"] as? String
{
profile_pictures.append(profile_picture)
}
}
}
catch{
print("A JSON parsing error occurred, here are the details:\n \(error)")
}
With this Code I get the following Error:
fatal error: Array index out of range
in the following line:
let pic = profile_pictures[indexPath.row]
The Problem is, that the array is empty. But I don't see the Problem. I think the function where I fill the array is correctly called.
Can someone help?
`tableViewcellForRowAtIndexPath: is getting called before TableData has data.
Ensure your number of rows in section returns the number of pictures:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return profile_pictures.count
}
This prevents a cell from being created when a picture doesn't exist at that index.

Resources