App crash when trying to delete cell - ios

I'm having a problem regarding a feature where You can delete a cell and so delete and event using an Alamofire JSON request.
When I swipe the cell and click delete, the app crashes, but the event get deleted successfully and with no errors, in facts on Laravel side I get the event deleted.
I tried everything, but I really can't figure out how to fix the crash.
Can someone help me please?
here is my .Swift code:
import UIKit
import Alamofire
class EventViewController: UITableViewController {
#objc var transition = ElasticTransition()
#objc let lgr = UIScreenEdgePanGestureRecognizer()
#objc let rgr = UIScreenEdgePanGestureRecognizer()
let rc = UIRefreshControl()
#IBOutlet weak var myTableView: UITableView!
var myTableViewDataSource = [NewInfo]()
let url = URL(string: "http://ns7records.com/staffapp/api/events/index")
override func viewDidLoad() {
super.viewDidLoad()
loadList()
// Add Refresh Control to Table View
if #available(iOS 10.0, *) {
tableView.refreshControl = rc
} else {
tableView.addSubview(rc)
}
// Configure Refresh Control
rc.addTarget(self, action: #selector(refreshTableData(_:)), for: .valueChanged)
let attributesRefresh = [kCTForegroundColorAttributeName: UIColor.white]
rc.attributedTitle = NSAttributedString(string: "Caricamento ...", attributes: attributesRefresh as [NSAttributedStringKey : Any])
DispatchQueue.main.async {
}
// MENU Core
// customization
transition.sticky = true
transition.showShadow = true
transition.panThreshold = 0.3
transition.transformType = .translateMid
// menu// gesture recognizer
lgr.addTarget(self, action: #selector(MyProfileViewController.handlePan(_:)))
rgr.addTarget(self, action: #selector(MyProfileViewController.handleRightPan(_:)))
lgr.edges = .left
rgr.edges = .right
view.addGestureRecognizer(lgr)
view.addGestureRecognizer(rgr)
}
#objc private func refreshTableData(_ sender: Any) {
// Fetch Table Data
//myTableViewDataSource.removeAll()
tableView.reloadData()
loadList()
}
func loadList(){
var myNews = NewInfo()
// URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
//
// })
let task = URLSession.shared.dataTask(with:url!) {
(data, response, error) in
if error != nil
{
print("ERROR HERE..")
}else
{
do
{
if let content = data
{
let myJson = try JSONSerialization.jsonObject(with: content, options: .mutableContainers)
//print(myJson)
if let jsonData = myJson as? [String : Any]
{
if let myResults = jsonData["data"] as? [[String : Any]]
{
//dump(myResults)
for value in myResults
{
if let myTitle = value["title"] as? String
{
//print(myTitle)
myNews.displayTitle = myTitle
}
if let myLocation = value["local"] as? String
{
myNews.location = myLocation
}
if let myDate = value["date"] as? String
{
myNews.date = myDate
}
if let myDescription = value["description"] as? String
{
myNews.description = myDescription
}
if let myCost = value["cost"] as? String
{
myNews.cost = myCost
}
if let myNumMembers = value["num_members"] as? String
{
myNews.num_members = myNumMembers
}
if let myNumMembers_conf = value["num_members_confirmed"] as? String
{
myNews.num_members_confirmed = myNumMembers_conf
}
if let myStartEvent = value["time_start"] as? String
{
myNews.startEvent = myStartEvent
}
if let myEndEvent = value["time_end"] as? String
{
myNews.endEvent = myEndEvent
}
if let myId = value["id"] as? Int
{
myNews.idEvent = myId
}
//x img
// if let myMultimedia = value["data"] as? [String : Any]
// {
if let mySrc = value["event_photo"] as? String
{
myNews.event_photo = mySrc
print(mySrc)
}
self.myTableViewDataSource.append(myNews)
}//end loop
dump(self.myTableViewDataSource)
DispatchQueue.main.async
{
self.tableView.reloadData()
self.rc.endRefreshing()
}
}
}
}
}
catch{
}
}
}
task.resume()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath)->CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myTableViewDataSource.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCell(withIdentifier: "reuseCell", for: indexPath)
let myImageView = myCell.viewWithTag(11) as! UIImageView
let myTitleLabel = myCell.viewWithTag(12) as! UILabel
let myLocation = myCell.viewWithTag(13) as! UILabel
let DateLabelCell = myCell.viewWithTag(14) as! UILabel
let numMembLabel = myCell.viewWithTag(15) as! UILabel
let numMembConfLabel = myCell.viewWithTag(16) as! UILabel
myTitleLabel.text = myTableViewDataSource[indexPath.row].displayTitle
myLocation.text = myTableViewDataSource[indexPath.row].location
DateLabelCell.text = myTableViewDataSource[indexPath.row].date
numMembLabel.text = myTableViewDataSource[indexPath.row].num_members
numMembConfLabel.text = myTableViewDataSource[indexPath.row].num_members_confirmed
if let imageURLString = myTableViewDataSource[indexPath.row].event_photo,
let imageURL = URL(string: AppConfig.public_server + imageURLString) {
myImageView.af_setImage(withURL: imageURL)
}
return myCell
}
//per passare da un viewcontroller a detailviewcontroller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? EventDetailViewController {
destination.model = myTableViewDataSource[(tableView.indexPathForSelectedRow?.row)!]
// Effetto onda
let vc = segue.destination
vc.transitioningDelegate = transition
vc.modalPresentationStyle = .custom
}
//menu
if let vc = segue.destination as? MenuViewController{
vc.transitioningDelegate = transition
vc.modalPresentationStyle = .custom
//endmenu
}
}
//menu slide
#objc func handlePan(_ pan:UIPanGestureRecognizer){
if pan.state == .began{
transition.edge = .left
transition.startInteractiveTransition(self, segueIdentifier: "menu", gestureRecognizer: pan)
}else{
_ = transition.updateInteractiveTransition(gestureRecognizer: pan)
}
}
//endmenuslide
////ximg
func loadImage(url: String, to imageView: UIImageView)
{
let url = URL(string: url )
URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data else
{
return
}
DispatchQueue.main.async
{
imageView.image = UIImage(data: data)
}
}.resume()
}
/// star to: (x eliminare row e x muove row)
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObjTemp = myTableViewDataSource[sourceIndexPath.item]
myTableViewDataSource.remove(at: sourceIndexPath.item)
myTableViewDataSource.insert(movedObjTemp, at: destinationIndexPath.item)
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete){
// print(parameters)
let idEvent = (myTableViewDataSource[indexPath.item].idEvent)
let parameters = [
// "id": UserDefaults.standard.object(forKey: "userid")! ,
"id" : idEvent,
] as [String : Any]
let url = "http://www.ns7records.com/staffapp/public/api/deleteevent"
print(url)
Alamofire.request(url, method:.post, parameters:parameters,encoding: JSONEncoding.default).responseJSON { response in
switch response.result {
case .success:
print(response)
let JSON = response.result.value as? [String : Any]
//self.myTableView.reloadData()
let alert = UIAlertController(title: "Yeah!", message: "Evento modificato con successo!", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
// let data = JSON! ["data"] as! NSDictionary
if let jsonData = JSON as? [String : Any]
{
print(jsonData)
self.myTableViewDataSource.remove(at : indexPath.item)
self.myTableView.deleteRows(at: [indexPath], with: .automatic)
let indexPath = IndexPath(item: 0, section: 0)
//self.myTableView.deleteRows(at: [indexPath], with: .fade)
//self.myTableView.reloadData()
// }
// }
//}
}
case .failure(let error):
print(error)
let alert = UIAlertController(title: "Aia", message: "Non puoi cancellare questo evento!", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
}
#IBAction func EditButtonTableView(_ sender: UIBarButtonItem) {
self.myTableView.isEditing = !self.myTableView.isEditing
sender.title = (self.myTableView.isEditing) ? "Done" : "Edit"
}
/// end to: (x eliminare row e x muove row)
}
// MARK: -
// MARK: UITableView Delegate
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}

Related

TableView not updating after button action

I'm relatively new to swift, and I'm trying to have a view that when it loads it will display some info on my tableView, then in the same view I have a textfield and a button
I want that the button performes an action that fetchs data from my server and updates my tableView
The problem is that the table is not being updated. How can I get the table to be updated?
CODE:
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = 80;
tableView.tableFooterView = UIView();
self.url = URL(string: "http://xxxxxxxx.com/xxxxx/api/produtos/listagem/favoritos/\(userID)");
downloadJson(_url: url!);
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return produtos.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProdutoCell1") as? ProdutoCell else{
return UITableViewCell()
}
cell.lbl_nome_json.text = produtos[indexPath.row].nome;
cell.lbl_categoria_json.text = produtos[indexPath.row].categoria;
cell.lbl_loja_json.text = produtos[indexPath.row].loja
//= produtos[indexPath.row].categoria;
// cell.lbl_loja.text = produtos[indexPath.row].loja;
if let imageURL = URL(string: "http://xxxxxxxxxx.com/myslim/api/"+produtos[indexPath.row].url){
DispatchQueue.global().async {
let data = try? Data(contentsOf: imageURL);
if let data = data{
let image = UIImage(data: data);
DispatchQueue.main.async {
cell.imgView_json.image = image;
}
}
}
}
return cell;
}
ACTION:
#IBAction func btn_search(_ sender: Any) {
if self.txt_search.text == "" {
let alert = UIAlertController(title:"Alert",message: "Insira algo para pesquisar",preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertAction.Style.default, handler: nil))
self.present(alert,animated: true,completion: nil)
}else{
var pesquisa = String();
pesquisa = self.txt_search.text!;
let url2 = URL(string: "http://xxxxxxxx.com/xxxxxx/api/produtos/listagem/favoritos/\(pesquisa)/\(self.userID)");
downloadJson(_url: url2!);
}
func downloadJson(_url: URL){
guard let downloadURL = url else {return}
URLSession.shared.dataTask(with: downloadURL){data, urlResponse, error in
guard let data = data, error == nil, urlResponse != nil else{
print("algo está mal");
return;
}
do{
let decoder = JSONDecoder();
let downloadedProdutos = try decoder.decode([ProdutoModel].self, from: data);
self.produtos = downloadedProdutos
print(downloadedProdutos);
DispatchQueue.main.async {
self.tableView.reloadData();
print("reload");
}
}catch{
print("algo mal depois do download")
}
}.resume();
}
EDIT
I added some print to see how many object were being returned on my downloadedProdutos variable, on the downloadJson() function.
And at the viewdidload I get 2 object, its normal because I only have 2 Products, but when the action is done I still get 2 object although I should get only 1 object
You need to set tableView.dataSource = self in viewWillAppear and it looks you missed func numberOfSections() -> Int method.
Add UITableViewDataSource like this
class YourViewController: UIViewController, UITableViewDataSource and it will recommend you required methods

Delete line of cell text in my text file in swift

i want to delete the line of text in the list file given under the if editMode == delete function which ever one was swiped on to delete i want it to delete that line of text in the file.
i read the file and parse it into the table view then when the user swipes to delete i want to delete the certain line of text in the file that cell.labelText?.text is if that makes sense. I cant seem to find anywhere that explains my particualr case. so please help me!!!
import UIKit
import Firebase
class ManageVC: UIViewController, UITabBarDelegate, UITableViewDataSource {
#IBOutlet var table: UITableView!
//parse sources text file
var sourcesList = [String:String]()
var sourcesArray = NSMutableArray()
var editMode = false
var refresher: UIRefreshControl!
var idgen = ""
func generateRandomDigits(_ digitNumber: Int) -> String {
var number = ""
for i in 0..<digitNumber {
var randomNumber = arc4random_uniform(10)
while randomNumber == 0 && i == 0 {
randomNumber = arc4random_uniform(10)
}
number += "\(randomNumber)"
}
return number
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sourcesArray.count
}
func tableSetup(){
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let source = sourcesArray[indexPath.row]
cell.textLabel?.text = "\((source as AnyObject).value(forKey: "sourcename")!)"
//cell.detailTextLabel?.text = "\((source as AnyObject).value(forKey: "sourceurl")!)"
return cell
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let source = sourcesArray[indexPath.row]
cell.textLabel?.text = "\((source as AnyObject).value(forKey: "sourcename")!)"
//cell.detailTextLabel?.text = "\((source as AnyObject).value(forKey: "sourceurl")!)"
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editMode == true {
if editingStyle == .delete{
sourcesArray.removeObject(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
}
var sourceUrlText: UITextField?
var ref: DatabaseReference!
#IBOutlet weak var addBtn: UIBarButtonItem!
#IBOutlet weak var editBtn: UIBarButtonItem!
override func viewDidLoad() {
DispatchQueue.main.async{
self.table.reloadData()
}
self.navigationItem.leftBarButtonItem = self.editButtonItem
refresher = UIRefreshControl()
refresher.addTarget(self, action: #selector(ManageVC.sourceRefresh), for: UIControl.Event.valueChanged)
table.addSubview(refresher)
ref = Database.database().reference()
super.viewDidLoad()
table.dataSource = self
let dir:NSURL = FileManager.default.urls(for: .documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).last! as NSURL
let fileurl = dir.appendingPathComponent("sources.list")
let mgr = FileManager.default
if mgr.fileExists(atPath: fileurl!.path) {
do {
let contents = try String(contentsOfFile: fileurl!.path, encoding: String.Encoding.utf8)
let reading = contents.components(separatedBy: "\n") as [String]
for i in 0..<reading.count {
let data : [String] = reading[i].components(separatedBy: ", ")
sourcesList["sourcename"] = "\(data[0])"
//sourcesList["sourceurl"] = "\(data[1])"
sourcesArray.add(sourcesList)
}
} catch let error as NSError {
print("Error: \(error)")
}
}
}
#IBAction func addBtnClicked(_ sender: Any) {
let addSource = UIAlertController(title: "Add Source:", message: nil, preferredStyle: .alert)
addSource.addTextField(configurationHandler: sourceUrlText)
let okAction = UIAlertAction(title: "Add", style: .default, handler: self.okHandler)
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
addSource.addAction(cancelAction)
addSource.addAction(okAction)
self.present(addSource, animated: true)
}
func okHandler(alert: UIAlertAction!){
if idgen == "" {
source()
performSegue(withIdentifier: "refreshingShow", sender: self)
}
}
func sourceUrlText(textField: UITextField!){
sourceUrlText = textField
sourceUrlText?.text = "http://"
}
#IBAction func editBtnClicked(_ sender: Any) {
addBtn.isEnabled = true
editBtn.isEnabled = false
editMode = true
}
override func viewDidAppear(_ animated: Bool) {
addBtn.isEnabled = false
editBtn.isEnabled = true
editMode = false
}
func source(){
let dir:NSURL = FileManager.default.urls(for: .documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).last! as NSURL
let fileurl = dir.appendingPathComponent("sources.list")
let string = ((self.sourceUrlText?.text)!) + "\n"
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: false)!
if FileManager.default.fileExists(atPath: fileurl!.path) {
var err:NSError?
if let fileHandle = FileHandle(forWritingAtPath: fileurl!.path) {
fileHandle.seekToEndOfFile()
fileHandle.write(data)
fileHandle.closeFile()
do {
self.table.reloadData()
refresher.endRefreshing()
let readSources = try String(contentsOfFile: fileurl!.path, encoding: String.Encoding.utf8)
print(readSources)
} catch {
}
}
else {
print("Can't open fileHandle \(err)")
}
}
else {
}
}
#objc func sourceRefresh() {
DispatchQueue.main.async{
self.tableSetup()
self.table.reloadData()
}
refresher.endRefreshing()
}
}

Firebase ServerValue.timestamp() continuously changes in firebase database

I am Trying to add an instance of ServerValue.timestamp() into my firebase database, when i run the app , the time stamps continuously increase here is the code, im not sure how to stop the timestamp from increasing in firebase
here is my custom class and my tableview class
class Story
{
var text: String = ""
var timestamp: String = ""
let ref: DatabaseReference!
init(text: String) {
self.text = text
ref = Database.database().reference().child("People").child("HomeFeed").child("Posts").childByAutoId()
}
init(snapshot: DataSnapshot)
{
ref = snapshot.ref
if let value = snapshot.value as? [String : Any] {
text = value["Post"] as! String
ref.updateChildValues(["timestamp":ServerValue.timestamp()])
let id = ref.key
Database.database().reference().child("People").child("HomeFeed").child("Posts").child("\(id)").child("timestamp").observeSingleEvent(of: .value) { (snapshot) in
let dope = snapshot.value as! Double
let x = dope / 1000
let date = NSDate(timeIntervalSince1970: x)
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .medium
DispatchQueue.main.async {
self.timestamp = formatter.string(from: date as Date)
self.timestamp = "\(value["timestamp"])"
}
}
}
}
func save() {
ref.setValue(toDictionary())
}
func toDictionary() -> [String : Any]
{
return [
"Post" : text,
"timestamp" : timestamp
]
}
}
here is the tableview class
class TableViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
let databaseRef = Database.database().reference()
#IBOutlet weak var tableView: UITableView!
var rub: StorageReference!
#IBAction func createpost(_ sender: Any) {
self.databaseRef.child("ProfileInfo").child(Auth.auth().currentUser!.uid).child("ProfilePic").observe(DataEventType.value) { (snapshot) in
let profpic = snapshot.value as? String
self.databaseRef.child("ProfileInfo").child(Auth.auth().currentUser!.uid).child("Full Name").observe(DataEventType.value) { (snapshot) in }
let fullname = snapshot.value as? String
if profpic == nil && fullname == nil {
let alert = UIAlertController(title: "Need to create profile", message: nil, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "To create profile", style: UIAlertActionStyle.default, handler: { action in self.performSegue(withIdentifier: "ToCreateprof", sender: nil)}))
alert.addAction(UIAlertAction(title: "Dissmiss", style: UIAlertActionStyle.default, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
}else {
self.performSegue(withIdentifier: "ToPost", sender: nil)
}
} //if no prof pic and name, no posting
}
#IBAction func toCreateorprofile(_ sender: Any) {
self.databaseRef.child("ProfileInfo").child(Auth.auth().currentUser!.uid).child("ProfilePic").observe(DataEventType.value) { (snapshot) in
let profpic = snapshot.value as? String
self.databaseRef.child("ProfileInfo").child(Auth.auth().currentUser!.uid).child("Full Name").observe(DataEventType.value) { (snapshot) in }
let fullname = snapshot.value as? String
if profpic != nil && fullname != nil {
self.performSegue(withIdentifier: "olduser", sender: nil)
}else {
self.performSegue(withIdentifier: "ToCreateprof", sender: nil)
}
}
}
let storiesRef = Database.database().reference().child("People").child("HomeFeed").child("Posts")
var stories = [Story]()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// download stories
storiesRef.observe(.value, with: { (snapshot) in
self.stories.removeAll()
for child in snapshot.children {
let childSnapshot = child as! DataSnapshot
let story = Story(snapshot: childSnapshot)
self.stories.insert(story, at: 0)
}
self.tableView.reloadData()
})
}
#objc func handleRefresh(_ refreshControl: UIRefreshControl) {
self.tableView.reloadData()
refreshControl.endRefreshing()
}
lazy var refreshControl: UIRefreshControl = {
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action:
#selector(TableViewController.handleRefresh(_:)),
for: UIControlEvents.valueChanged)
refreshControl.tintColor = UIColor.purple
return refreshControl
}()
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.reloadData()
self.tableView.addSubview(self.refreshControl)
tableView.delegate = self
tableView.dataSource = self
self.tableView.estimatedRowHeight = 92.0
self.tableView.rowHeight = UITableViewAutomaticDimension
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
// MARK: - Table view data source
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return stories.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Story Cell", for: indexPath) as! StoryTableviewcell
let story = stories[indexPath.row]
cell.story = story
self.databaseRef.child("ProfileInfo").child(Auth.auth().currentUser!.uid).child("Full Name").observe(.value) { (snapshot) in
let name = snapshot.value as? String
if name != nil {
cell.fullnamepost.text = name
}
}
rub = Storage.storage().reference().storage.reference(forURL:"gs://people-3b93c.appspot.com").child("ProfilePic").child(Auth.auth().currentUser!.uid)
if rub != nil {
// Create a UIImage, add it to the array
rub.downloadURL(completion: { (url, error) in
if error != nil {
print(error?.localizedDescription as Any)
return
}
URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
if error != nil {
print(error as Any)
return
}
guard let imageData = UIImage(data: data!) else { return }
DispatchQueue.main.async {
cell.profimage.image = imageData
}
}).resume()
})
}
return cell
}
}

Pull to Refresh on tableView

I want to pull to refresh for my RSS feed news app. I using navigation controller and table view controller. How should I do on Table View Controller? What should we add? My code is here.
class TableviewController: UITableViewController {
var items : Array<Item> = []
var entries : Array<Entry> = []
override func viewDidLoad() {
super.viewDidLoad()
loadRSS()
loadAtom()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
let item:Item = self.items[indexPath.row]
cell.textLabel?.text = item.title
cell.detailTextLabel?.text = self.pubDateStringFromDate(item.pubDate! as Date)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = self.items[indexPath.row]
let url:URL = URL(string: item.link!)!
let safariViewController = SFSafariViewController(url: url, entersReaderIfAvailable: true)
present(safariViewController, animated: true, completion: nil)
}
func loadRSS() {
let feedUrlString:String = "websiteurl"
Alamofire.request(feedUrlString).response { response in
if let data = response.data, let _ = String(data: data, encoding: .utf8) {
TIFeedParser.parseRSS(xmlData: data as NSData, completionHandler: {(isSuccess, channel, error) -> Void in
if (isSuccess) {
self.items = channel!.items!
self.tableView.reloadData()
}
if (response.error != nil) {
print((response.error?.localizedDescription)! as String)
}
})
}
}
}
func loadAtom() {
let feedUrlString:String = "websiteurl"
Alamofire.request(feedUrlString).response { response in
if let data = response.data, let _ = String(data: data, encoding: .utf8) {
TIFeedParser.parseAtom(xmlData: data as NSData, completionHandler: {(isSuccess, feed, error) -> Void in
if (isSuccess) {
self.entries = feed!.entries!
self.tableView.reloadData()
}
if (error != nil) {
print((error?.localizedDescription)! as String)
}
})
}
}
}
func pubDateStringFromDate(_ pubDate:Date)->String {
let format = DateFormatter()
format.dateFormat = "yyyy/M/d HH:mm"
let pubDateString = format.string(from: pubDate)
return pubDateString
}
}
1) Declare an property of type UIRefreshControl as:
var refreshControl = UIRefreshControl()
2) In viewDidLoad()method add this refreshControl to your table view as:
self.refreshControl.addTarget(self, action: #selector(loadRSS), for: .valueChanged)
if #available(iOS 10, *){
self.tableView.refreshControl = self.refreshControl
}else{
self.tableView.addSubview(self.refreshControl)
}
Declare a property refreshControl in your TableViewController as
var refreshControl:UIRefreshControl?
The in viewDidLoad() function add the following code
refreshControl?.addTarget(self, action: #selector(loadRSS), for: .valueChanged)
self.tableView.addSubview(refreshControl!)
Update your loadRSS() function as
func loadRSS() {
let feedUrlString:String = "websiteurl"
Alamofire.request(feedUrlString).response { response in
self.refreshControl?.endRefreshing(
if let data = response.data, let _ = String(data: data, encoding: .utf8) {
TIFeedParser.parseRSS(xmlData: data as NSData, completionHandler: {(isSuccess, channel, error) -> Void in
if (isSuccess) {
self.items = channel!.items!
self.tableView.reloadData()
}
if (response.error != nil) {
print((response.error?.localizedDescription)! as String)
}
})
}
}
}
Please refer following code , as i have added pull to refresh control on your code.
class TableviewController: UITableViewController {
var items : Array<Item> = []
var entries : Array<Entry> = []
var pullToFrefreshNews:UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
loadRSS()
loadAtom()
self.addPulltoRefrehs()
}
func addPulltoRefrehs() {
self.pullToFrefreshNews = UIRefreshControl()
self.pullToFrefreshNews.addTarget(self, action: #selector(TableviewController.loadRSS), for: UIControlEvents.valueChanged)
self.newsTableVU.addSubview(pullToFrefreshNews)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
let item:Item = self.items[indexPath.row]
cell.textLabel?.text = item.title
cell.detailTextLabel?.text = self.pubDateStringFromDate(item.pubDate! as Date)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = self.items[indexPath.row]
let url:URL = URL(string: item.link!)!
let safariViewController = SFSafariViewController(url: url, entersReaderIfAvailable: true)
present(safariViewController, animated: true, completion: nil)
}
func loadRSS() {
let feedUrlString:String = "websiteurl"
Alamofire.request(feedUrlString).response { response in
if let data = response.data, let _ = String(data: data, encoding: .utf8) {
TIFeedParser.parseRSS(xmlData: data as NSData, completionHandler: {(isSuccess, channel, error) -> Void in
if (isSuccess) {
self.items = channel!.items!
self.tableView.reloadData()
}
if (response.error != nil) {
print((response.error?.localizedDescription)! as String)
}
})
}
}
}
func loadAtom() {
let feedUrlString:String = "websiteurl"
Alamofire.request(feedUrlString).response { response in
if let data = response.data, let _ = String(data: data, encoding: .utf8) {
TIFeedParser.parseAtom(xmlData: data as NSData, completionHandler: {(isSuccess, feed, error) -> Void in
if (isSuccess) {
self.entries = feed!.entries!
self.tableView.reloadData()
}
if (error != nil) {
print((error?.localizedDescription)! as String)
}
})
}
}
}
func pubDateStringFromDate(_ pubDate:Date)->String {
let format = DateFormatter()
format.dateFormat = "yyyy/M/d HH:mm"
let pubDateString = format.string(from: pubDate)
return pubDateString
}
}

How to show first data in table view while fetch data from api

I have one collection view and it have some 5 cells. Which are I am fetching from api to show the cells data in collection view. And when user click any cell, that approprate data will display in below table view.
Now, every thing works fine. But when I load first time my view. No data are displaying in my table view... What I mean is? By default first data of collection view cell have to show in tableview. But I am not getting or not able to display.
If I click any cell only, I can see the data in my table view. But what I need is - By default first cell of collection view have to display in table view when ever i open that screen
How to do that?
Here is my code:
#IBOutlet var BTCollectionView: UICollectionView!
#IBOutlet var DLTableView: UITableView!
var BTdata = [BTData]()
var Dealsdata = [DealsData]()
override func viewDidLoad()
{
super.viewDidLoad()
// nib for custom cell (table view)
let nib = UINib(nibName:"DealsListTableCell", bundle: nil)
DLTableView.registerNib(nib, forCellReuseIdentifier: "DealCell")
ListBusinessTypes()
}
// Values from Api for Business Types
func ListBusinessTypes()
{
let token = NSUserDefaults.standardUserDefaults().valueForKey("access_token") as! String
let headers = ["x-access-token": token]
let request = NSMutableURLRequest(URL: NSURL(string: "httpsome url")!,
cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0)
request.HTTPMethod = "GET"
request.allHTTPHeaderFields = headers
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil)
{
print(error)
let ErrorAlert = UIAlertController(title: "Error", message: "Problem with internet connectivity or server, please try after some time", preferredStyle: UIAlertControllerStyle.Alert)
// add an action (button)
ErrorAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
// show the alert
self.presentViewController(ErrorAlert, animated: true, completion: nil)
}
else
{
if let json = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? Dictionary<String,AnyObject>
{
let success = json["success"] as? Int
if(success == 1)
{
if let typeValues = json["data"] as? [NSDictionary]
{
dispatch_async(dispatch_get_main_queue(),{
for item in typeValues
{
self.BTdata.append(BTData(json:item))
self.BTCollectionView.reloadData()
}
})
}
}
else
{
let message = json["message"] as? String
print(message)
let ServerAlert = UIAlertController(title: "Error", message: message, preferredStyle: UIAlertControllerStyle.Alert)
// add an action (button)
ServerAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
// show the alert
self.presentViewController(ServerAlert, animated: true, completion: nil)
}
}
}
})
dataTask.resume()
}
// Mark : Collection View Delegate and Datasource(Business Type)
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return BTdata.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
let cell: DDLCollectionCell = collectionView.dequeueReusableCellWithReuseIdentifier("HCollectionCell", forIndexPath: indexPath) as! DDLCollectionCell
cell.BTName.text = BTdata[indexPath.row].BTNames
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
ListDeals(BTdata[indexPath.row].BTIds!)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
// number of rows
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return Dealsdata.count
}
// calling each cell based on tap and users ( premium / non premium )
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let tabcell = tableView.dequeueReusableCellWithIdentifier("DealCell") as! DealsListTableCell
tabcell.DealName.text = Dealsdata[indexPath.row].DealNames
if let imgURL = NSURL(string: Dealsdata[indexPath.row].DealImageUrls!)
{
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request)
{
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
tabcell.DealImage.image = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
Imgtask.resume()
}
else
{
tabcell.DealImage.image = UIImage(named: "FBLogo")
}
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US")
formatter.dateFormat = "yyyy-MM-dd'T'hh:mm:ss.SSSSxxx"
let date = formatter.dateFromString(Dealsdata[indexPath.row].DealExpiry!)
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateFormatter.timeStyle = .NoStyle
dateFormatter.locale = NSLocale(localeIdentifier: "en_US")
let FormattedDate = dateFormatter.stringFromDate(date!)
tabcell.RegPriceLabel.text = String(Dealsdata[indexPath.row].DealRegularPrice!)
tabcell.SalePriceLabel.text = String(Dealsdata[indexPath.row].DealSalePrice!)
tabcell.DealExpiryDate.text = "Expiries on : "+FormattedDate
let BArrayValue:NSDictionary = Dealsdata[indexPath.row].DealBusinessDetails!
let BName = BArrayValue.valueForKey("business_name") as! String
let BImage = BArrayValue.valueForKey("images") as! NSArray
let BMainImage = BImage[0] as! NSDictionary
let FinalImage = BMainImage.valueForKey("url") as! String
if let imgURL2 = NSURL(string: FinalImage)
{
let request: NSURLRequest = NSURLRequest(URL: imgURL2)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request)
{
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
tabcell.DealBusinessImage.image = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
Imgtask.resume()
}
else
{
tabcell.DealBusinessImage.image = UIImage(named: "FBLogo")
}
let BLatLng = Dealsdata[indexPath.row].DealCoordinates
let UserLocation = CLLocation(latitude: NewCurrentLatitude, longitude: NewCurrentLongitude)
let BusinessLocation = CLLocation(latitude: BLatLng![0] as! Double, longitude: BLatLng![1] as! Double)
let distance = UserLocation.distanceFromLocation(BusinessLocation) / 1000
tabcell.DealBusinessNameWithDistance.text = BName+" - "+String(format: "%.1f",distance)+" Km"
return tabcell
}
Please help me out. Thanks!
Does i need to change any thing in below line:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
ListDeals(BTdata[indexPath.row].BTIds!)
}
Try to call ListDeals(BTdata[0].BTIds!) after you loaded the data from your API.
...
if let typeValues = json["data"] as? [NSDictionary]
{
dispatch_async(dispatch_get_main_queue(),{
for item in typeValues
{
self.BTdata.append(BTData(json:item))
self.BTCollectionView.reloadData()
}
ListDeals(BTdata[0].BTIds!)
})
}
...

Resources