sorting cells in table view through buttons - ios

I have a table view with data from API.
Each cell has several properties. What I want, is to sorting cells by chosen button (these three rectangles).
I dont know exactly how should I do it. I think I need tree methods for that, each for clicked button. But how to deal with sorting and reloading data?
Thanks for answer.
override func viewDidLoad() {
super.viewDidLoad()
callAlamo(url: urlAPI)
}
func callAlamo(url: String){
Alamofire.request(url).responseJSON(completionHandler: {
response in
self.parseData(JSONData: response.data!)
})
}
func parseData(JSONData: Data){
do{
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard
// print(readableJSON)
if let rows = readableJSON["rows"] as? [JSONStandard]{
print(rows)
for i in 0..<rows.count{
let row = rows[i]
if let name = row["name"] as? String{
if name.isEmpty == false{
if let status = row["status"] as? String{
if let counter = row["counter"] as? String{
items.append(Station.init(place: name, counter: counter, status: status))
DispatchQueue.main.async {
self.tableView.reloadData()
}
}else{
let counter = "no data"
items.append(Station.init(place: name, stationsCount: counter, status: status))
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
}
}
}catch{
print(error)
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
cell.place.text = items[indexPath.row].place
cell.stationsCount.text = items[indexPath.row].stationsCount
let num = items[indexPath.row].status
let value = picDictionary[num!]
print(num!, value!)
cell.statusSign.image = UIImage(named: value!)
return cell
}
Sometimes I get null value from API, and then, I assing value to string "no data".
if let counter = row["counter"] as? String{
/////code
else{
let counter = "no data"
//////
}
And I dont want to let these values taking part in sorting process, because they are not numbers. How to do that?

Make three actions for your three buttons and sort the array with it and reload the table after that.
#IBAction func sortWithName(_ sender: UIButton) {
items.sort { $0.place < $1.place }
self.tableView.reloadData()
}
#IBAction func sortWithStatus(_ sender: UIButton) {
items.sort { $0.status < $1.status }
self.tableView.reloadData()
}
#IBAction func sortWithStatusCount(_ sender: UIButton) {
//stationsCount is looks like number so sort it using compare with numeric option
items.sort { $0.stationsCount.compare($1.stationsCount, options: .numeric) == .orderedAscending }
self.tableView.reloadData()
}
Edit: Declare one more array named allItems same way you have declared your items array. One more thing I haven't noticed first that you are reloading tableView inside for loop so that it will reload n(o) times instead of that you need to reload it once after the for loop also before reloading the tableView and set allItems with your items also you are making too many if condition where you can combine it in once.
for row in rows {
if let name = row["name"] as? String,
let status = row["status"] as? String,
!name.isEmpty {
if let counter = row["counter"] as? String {
items.append(Station.init(place: name, counter: counter, status: status))
}else{
let counter = "no data"
items.append(Station.init(place: name, stationsCount: counter, status: status))
}
}
}
//Set allItems with items
self.allItems = items
DispatchQueue.main.async {
self.tableView.reloadData()
}
Now change all your button actions like this.
ke three actions for your three buttons and sort the array with it and reload the table after that.
#IBAction func sortWithName(_ sender: UIButton) {
items = allItems.sorted { $0.place < $1.place }
self.tableView.reloadData()
}
#IBAction func sortWithStatus(_ sender: UIButton) {
items = allItems.sorted { $0.status < $1.status }
self.tableView.reloadData()
}
#IBAction func sortWithStatusCount(_ sender: UIButton) {
//Filter your array first
items = allItems.filter { $0.stationsCount != "no data" }
//stationsCount is looks like number so sort it using compare with numeric option
items.sort { $0.stationsCount.compare($1.stationsCount, options: .numeric) == .orderedAscending }
self.tableView.reloadData()
}

Related

Index out of range when i use to celll( Swift)

people, I have this issue when I try back image from different cell
(Thread 1: Fatal error: Index out of range)
what I'm doing here ?
I'm trying to build an Instagram clone and in my home view controller that what should posts show up. I make navigation with a table view and that table view has 2 cell with the different identifier. cell number 1 it's a header that brings data from users table to my username label and profile image. and cell number 2 its for posts its should bring post data like image and caption. I use firebase database.
my code :
import UIKit
import FirebaseAuth
import FirebaseDatabase
class HomeViewController: UIViewController ,UITableViewDelegate {
#IBOutlet weak var tableview: UITableView!
var posts = [Post]()
var users = [UserD]()
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
loadposts()
userDetal()
// var post = Post(captiontxt: "test", photoUrlString: "urll")
// print(post.caption)
// print(post.photoUrl)
}
func loadposts() {
Database.database().reference().child("posts").observe(.childAdded){ (snapshot: DataSnapshot)in
print(Thread.isMainThread)
if let dict = snapshot.value as? [String: Any]{
let captiontxt = dict["caption"] as! String
let photoUrlString = dict["photoUrl"] as! String
let post = Post(captiontxt: captiontxt, photoUrlString: photoUrlString)
self.posts.append(post)
print(self.posts)
self.tableview.reloadData()
}
}
}
func userDetal() {
Database.database().reference().child("users").observe(.childAdded){ (snapshot: DataSnapshot)in
print(Thread.isMainThread)
if let dict = snapshot.value as? [String: Any]{
let usernametxt = dict["username"] as! String
let profileImageUrlString = dict["profileImageUrl"] as! String
let user = UserD(usernametxt: usernametxt, profileImageUrlString: profileImageUrlString)
self.users.append(user)
print(self.users)
self.tableview.reloadData()
}
}
}
#IBAction func logout(_ sender: Any) {
do {
try Auth.auth().signOut()
}catch let logoutErrorr{
print(logoutErrorr)
}
let storyboard = UIStoryboard(name: "Start", bundle: nil)
let signinVC = storyboard.instantiateViewController(withIdentifier: "SigninViewController")
self.present(signinVC, animated: true, completion: nil)
}
}
extension HomeViewController: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return users.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0{
let cell = tableview.dequeueReusableCell(withIdentifier: "imagecell", for: indexPath) as! PostCellTableViewCell
cell.postimage.image = nil
cell.tag += 1
let tag = cell.tag
cell.captionLabel.text = posts[indexPath.row].caption
let photoUrl = posts[indexPath.row].photoUrl
getImage(url: photoUrl) { photo in
if photo != nil {
if cell.tag == tag {
DispatchQueue.main.async {
cell.postimage.image = photo
}
}
}
}
return cell
} else if indexPath.row == 1 {
let cell = tableview.dequeueReusableCell(withIdentifier: "postcell", for: indexPath) as! HeaderTableViewCell
cell.userimage.image = nil
cell.tag += 1
let tag = cell.tag
cell.usernamelabel.text = users[indexPath.row].username
//Error showing here????????????????????????????????????
let profileImageUrl = users[indexPath.row].profileImageUrl
getImage(url: profileImageUrl) { photo in
if photo != nil {
if cell.tag == tag {
DispatchQueue.main.async {
cell.userimage.image = photo
}
}
}
}
return cell
}
return UITableViewCell()
}
func getImage(url: String, completion: #escaping (UIImage?) -> ()) {
URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
if error == nil {
completion(UIImage(data: data!))
} else {
completion(nil)
}
}.resume()
}
}
try this one.
cell.tag = indexpath.row
What is the content of users array ?
Are you sure you want to define as many sections as users or as many rows ?
In this case use
func numberOfRows(in tableView: NSTableView) -> Int {
return users.count
}
As explained, you need to rewrite completely cellForRowAt
It should look like this :
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
if row < users.count {
let user = users[row]
if let cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "CellID"), owner: self) {
(cellView as! NSTableCellView).textField?.stringValue = user.name
// do the same for all the fields you need to set
return cellView
} else {
return nil
}
}
return nil
}
thanx, my friend, I found a good way to contain my cell. for post cell, i just use cellForRowAt and but the post data. for header cell i use viewForHeaderInSection
and but my user data with heightForHeaderInSection. to make the high for a view

Swift Compiler Warning : Result of call to 'save(defaults:)' is unused

So my table view is not loading anything and I think it's because of this warning that I get. It saids the save function is not being used so how can it load something that is not saved. What I am saving is the indexPath and Section of the row that the user selected via a button action in the row.
Warning:
Result of call to 'save(defaults:)' is unused
Code:
func saveSorting(_ dataIdBlock: (Any) -> String) {
guard let items = self.items else { return }
for (section, rows) in items.enumerated() {
for (row, item) in rows.enumerated() {
let indexPath = IndexPath(row: row, section: section)
let dataId = dataIdBlock(item)
let ordering = DataHandling(dataId: dataId, indexPath: indexPath)
// Warning is here
ordering.save(defaults: indexPath.defaultsKey)
}
}
}
}
NSCoder Class for DataHandling / ordering.save
DataHandling.swift
class DataHandling: NSObject, NSCoding {
var indexPath: IndexPath?
var dataId: String?
init(dataId: String, indexPath: IndexPath) {
super.init()
self.dataId = dataId
self.indexPath = indexPath
}
required init(coder aDecoder: NSCoder) {
if let dataId = aDecoder.decodeObject(forKey: "dataId") as? String {
self.dataId = dataId
}
if let indexPath = aDecoder.decodeObject(forKey: "indexPath") as? IndexPath {
self.indexPath = indexPath
}
}
func encode(with aCoder: NSCoder) {
aCoder.encode(dataId, forKey: "dataId")
aCoder.encode(indexPath, forKey: "indexPath")
}
func save(defaults box: String) -> Bool {
let defaults = UserDefaults.standard
let savedData = NSKeyedArchiver.archivedData(withRootObject: self)
defaults.set(savedData, forKey: box)
return defaults.synchronize()
}
convenience init?(defaults box: String) {
let defaults = UserDefaults.standard
if let data = defaults.object(forKey: box) as? Data,
let obj = NSKeyedUnarchiver.unarchiveObject(with: data) as? DataHandling,
let dataId = obj.dataId,
let indexPath = obj.indexPath {
self.init(dataId: dataId, indexPath: indexPath)
} else {
return nil
}
}
class func allSavedOrdering(_ maxRows: Int) -> [Int: [DataHandling]] {
var result: [Int: [DataHandling]] = [:]
for section in 0...1 {
var rows: [DataHandling] = []
for row in 0..<maxRows {
let indexPath = IndexPath(row: row, section: section)
if let ordering = DataHandling(defaults: indexPath.defaultsKey) {
rows.append(ordering)
}
rows.sort(by: { $0.indexPath! < $1.indexPath! })
}
result[section] = rows
}
return result
}
}
Other code I'm using:
// Number of Rows in Section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items?[section].count ?? 0
}
// Number of Sections
func numberOfSections(in tableView: UITableView) -> Int {
return self.items?.count ?? 0
}
Saving it with:
saveSorting() { "\($0)" }
Loading it in ViewDidLoad:
func fetchData() {
// Load Data from Server to testArray
retrieveData()
// request from remote or local
data = [testArray]
// Update the items to first section has 0 elements,
// and place all data in section 1
items = [[], data ?? []]
// apply ordering
applySorting() { "\($0)" }
// save ordering
saveSorting() { "\($0)" }
// refresh the table view
myTableView.reloadData()
}
Loading Code:
// Loading
func applySorting(_ dataIdBlock: (Any) -> String) {
// get all saved ordering
guard let data = self.data else { return }
let ordering = DataHandling.allSavedOrdering(data.count)
var result: [[Any]] = [[], []]
for (section, ordering) in ordering {
guard section <= 1 else { continue } // make sure the section is 0 or 1
let rows = data.filter({ obj -> Bool in
return ordering.index(where: { $0.dataId == .some(dataIdBlock(obj)) }) != nil
})
result[section] = rows
}
self.items = result
}
The DataHandling instance's save(defaults:) function technically returns a value, even if you don't use it. To silence this warning, assign it to _ to signify that you don't intend to use the result value, e.g.:
_ = ordering.save(defaults: indexPath.defaultsKey)
or
let _ = ordering.save(defaults: indexPath.defaultsKey)
Just to be clear, this is almost definitely not why your tableview is not loading data. It should be pretty insignificant. The indexPath.defaultsKey is being saved (assuming the API works).

Guidance on Core Data with Swift 3

Not looking for code (wouldn't hurt though) just looking to know how I should go about this. I have an app which is like a blog reader. I have information in a MYSQL database which is taken with JSON, placed in a jsonArray and then placed in an array to be shown in a table view. In that table view I generally have all my objects in 1 section. Each row/object has a button when clicked it moves that row into another section. I also have a search controller to search through the main section (Section 1).
How do I save the order or position of the rows to Core Data?
For example: I have 0 rows in Section 0 and 5 rows in Section 1, I click the button on one of the rows in Section 1 and it moves that row to Section 0, now Section 0 has 1 row while Section 1 has 4 rows. How do I save this new tableview order to Core Data? I just want to save the rows positions, so the app remembers which section that selected row was in.
Do I save the indexPath of the row in the section?
When adding an entity and attributes, what do I use to save?
Also, its a mysql reader so when the tableview is reloaded and a new content is added, will it still show since the tableview will be reading from core data?
I'm learning Core Data (Swift 3 code) but just having trouble using it for this app.
Thank you for helping out!
Use UserDefaults to save the ordering data if you don't need to save the whole data from MySQL database. Define a class only contains dataId and indexPath:
class DataOrdering: NSObject, NSCoding {
var indexPath: IndexPath?
var dataId: String?
init(dataId: String, indexPath: IndexPath) {
super.init()
self.dataId = dataId
self.indexPath = indexPath
}
required init(coder aDecoder: NSCoder) {
if let dataId = aDecoder.decodeObject(forKey: "dataId") as? String {
self.dataId = dataId
}
if let indexPath = aDecoder.decodeObject(forKey: "indexPath") as? IndexPath {
self.indexPath = indexPath
}
}
func encode(with aCoder: NSCoder) {
aCoder.encode(dataId, forKey: "dataId")
aCoder.encode(indexPath, forKey: "indexPath")
}
func save(defaults key: String) -> Bool {
let defaults = UserDefaults.standard
let savedData = NSKeyedArchiver.archivedData(withRootObject: self)
defaults.set(savedData, forKey: key)
return defaults.synchronize()
}
convenience init?(defaults key: String) {
let defaults = UserDefaults.standard
if let data = defaults.object(forKey: key) as? Data,
let obj = NSKeyedUnarchiver.unarchiveObject(with: data) as? DataOrdering,
let dataId = obj.dataId,
let indexPath = obj.indexPath {
self.init(dataId: dataId, indexPath: indexPath)
} else {
return nil
}
}
class func allSavedOrdering(_ maxRows: Int) -> [Int: [DataOrdering]] {
var result: [Int: [DataOrdering]] = [:]
for section in 0...1 {
var rows: [DataOrdering] = []
for row in 0..<maxRows {
let indexPath = IndexPath(row: row, section: section)
if let ordering = DataOrdering(defaults: indexPath.defaultsKey) {
rows.append(ordering)
}
rows.sort(by: { $0.indexPath! < $1.indexPath! })
}
result[section] = rows
}
return result
}
}
Playground sample:
let data = DataOrdering(dataId: "1", indexPath: IndexPath(row: 0, section: 0))
let savedData = NSKeyedArchiver.archivedData(withRootObject: data)
let obj = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? DataOrdering
obj?.dataId // print: "1"
obj?.indexPath // print: [0,0]
Use save function to save with a "key" and read it back by DataOrdering(defaults: "key")
UPDATED
Added codes for a view controller to use this class:
extension IndexPath {
var defaultsKey: String { return "data_ordering_\(section)_\(row)" }
}
class ViewController: UITableViewController {
var data: [Any]?
var items: [[Any]]?
func fetchData() {
// request from remote or local
data = [1, 2, 3, "a", "b", "c"] // sample data
// Update the items to first section has 0 elements,
// and place all data in section 1
items = [[], data ?? []]
// apply ordering
applySorting() { "\($0)" }
// save ordering
saveSorting() { "\($0)" }
// refresh the table view
tableView.reloadData()
}
func applySorting(_ dataIdBlock: (Any) -> String) {
// get all saved ordering
guard let data = self.data else { return }
let ordering = DataOrdering.allSavedOrdering(data.count)
var result: [[Any]] = [[], []]
for (section, ordering) in ordering {
guard section <= 1 else { continue } // make sure the section is 0 or 1
let rows = data.filter({ obj -> Bool in
return ordering.index(where: { $0.dataId == .some(dataIdBlock(obj)) }) != nil
})
result[section] = rows
}
self.items = result
}
func saveSorting(_ dataIdBlock: (Any) -> String) {
guard let items = self.items else { return }
for (section, rows) in items.enumerated() {
for (row, item) in rows.enumerated() {
let indexPath = IndexPath(row: row, section: section)
let dataId = dataIdBlock(item)
let ordering = DataOrdering(dataId: dataId, indexPath: indexPath)
ordering.save(defaults: indexPath.defaultsKey)
}
}
}
#IBAction func buttonMoveToSectionTapped(_ sender: UIButton) {
// if the sender's tag is row index
// or you can get indexPath by tableView.indexPath(for: cell) function too
let row = sender.tag
// move this item from section 1 to section 0 (last position)
if let item = items?[1].remove(at: row) {
items?[0].append(item)
}
// Save all sorting
saveSorting() { "\($0)" }
tableView.reloadData() // refresh table view
}
override func numberOfSections(in tableView: UITableView) -> Int {
return self.items?.count ?? 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items?[section].count ?? 0
}
}

UITableView doesn't show the realm objects that it should show

I have a problem with the content of a tableView. It doesn't show me the realm objects, that I asked for. Here's my code:
At the top of the class i declared this variable:
let newPlan = TrainingPlan()
Then I have this button action, which is copying the exercise objects, put them in an array an add this to realm. I did this, because I only want to change this copied array:
#IBAction func savePlanAction(_ sender: AnyObject) {
if planNameTextField.text!.isEmpty{
planNameFehlerLabel.isHidden = false
}
else{
newPlan.name = planNameTextField.text!
newPlan.creationDate = NSDate() as Date
let selectedExcercises = loadSelectedExcercises()
if selectedExcercises != nil{
for var i in (0..<selectedExcercises!.count){
excerciseCopies.append(selectedExcercises![i])
do{
try realm.write{
realm.add(excerciseCopies[i])
}
}
catch{
print(error)
}
}
try! realm.write{
realm.add(newPlan)
}
for object in excerciseCopies {
do{
try realm.write{
newPlan.excercises.append(object)
}
}
catch{
print(error)
}
}
performSegue(withIdentifier: "savePlan", sender: self)
}
else{
uebungFehlerLabel.isHidden = false
}
}
}
Then I give the newPlan object to another ViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier! == "savePlan" {
let tct = segue.destination as! TrainingPlanConfTableViewController
tct.plan = newPlan
}
}
Now in the next class I want to show all exercise objects from the copied array in a tableView, but the tableView doesn't show anything:
class TrainingPlanConfTableViewController: UITableViewController {
//Properties
let realm = try! Realm()
var excercisesFromPlan: Results<Excercise>?{
didSet{
tableView.reloadData()
}
}
var plan: TrainingPlan?
//Lifecycle
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadExcercisesFromPlan()
}
//Request
func loadExcercisesFromPlan(){
if plan != nil{
let predicate = NSPredicate(format: "trainingsplan = %#", plan!)
excercisesFromPlan = realm.objects(Excercise.self).filter(predicate)
}
}
//Tableview Funktionen
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if excercisesFromPlan != nil{
return excercisesFromPlan!.count
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: TrainingPlanConfTableViewCell = tableView.dequeueReusableCell(withIdentifier: "PlanConfCell") as! TrainingPlanConfTableViewCell
let excercise = excercisesFromPlan![indexPath.row]
cell.nameLabel.text = excercise.name
return cell
}
}
I'm pretty new in Swift and I can't find the issue. Is the predicate seated wrong? I would be thankful for any help! If you need any more information, for example the data model etc, pls feel free to ask
Since you didn't include the code for your models, there's no way to know for sure if your predicate is correct or not.
What I can tell is the TrainingPlan has a exercises property on it that you should use instead of querying for the same thing.
You would just need to change excercisesFromPlan to be a List instead of a Results
var excercisesFromPlan: List<Excercise>?
and change loadExcercisesFromPlan to get it
func loadExcercisesFromPlan() {
excercisesFromPlan = plan?.excercises
}

return data in DetailTableView (swift)

In my app I have two table views. The first table view has a set number of cells. These cells will always be the same and will never change The above table view will always have the 4 cells and never more. On my server I have my API which has routes for each of these cells.
For example:
GET - myAPI/Air
GET - myAPI/history
GET - myAPI/train
GET - myAPI/taxi
And each routes send backs different data
mainTablewView:
import UIKit
enum NeededAPI {
case Air
case History
case Train
case Taxi
}
class mainTableViewController : UITableViewController {
struct WeatherSummary {
var id: String
}
var testArray = NSArray()
var manuArray = NSArray()
// Array of sector within our company
var selectSector: [String] = ["Air", "History","Train","Taxi"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = 80.0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.selectSector.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("sectorList", forIndexPath: indexPath)
// Configure the cell...
if selectSector.count > 0 {
cell.textLabel?.text = selectSector[indexPath.row]
}
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "AirSegue"){
if let destination = segue.destinationViewController as? AirTableViewController {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow!
if let row:Int = indexPath.row {
destination.apiThatNeedsToBeCalled = .Air
}
}
}
if (segue.identifier == "HistorySegue"){
if let destination = segue.destinationViewController as? HistoryTableViewController {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow!
if let row:Int = indexPath.row {
destination.apiThatNeedsToBeCalled = .History
}
}
}
if (segue.identifier == "TrainSgue"){
if let destination = segue.destinationViewController as? TrainTableViewController {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow!
if let row:Int = indexPath.row {
destination.apiThatNeedsToBeCalled = .Train
}
}
}
if (segue.identifier == "TaxiSegue"){
if let destination = segue.destinationViewController as? TaxiTableViewController {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow!
if let row:Int = indexPath.row {
destination.apiThatNeedsToBeCalled = .Taxi
}
}
}
}
}
and Post
import Foundation
class Post : CustomStringConvertible {
var userId:Int
var title: String
init(userid:Int , title:String){
self.userId = userid
self.title = title
}
var description : String { return String(userId) }
}
When user selects cell you set the correct value for the apiThatNeedsToBeCalled. Once you do this, code inside the didSet will get executed and it should call the function which calls the appropriate API.
to other tableView :
import UIKit
class AirTableViewController: UITableViewController {
var postCollection = [Post]()
var apiThatNeedsToBeCalled:NeededAPI = .Air {
didSet {
//check which API is set and call the function which will call the needed API
AirLine()
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var apiThatNeedsToBeCalled:NeededAPI = .Air {
didSet {
//check which API is set and call the function which will call the needed API
AirLine()
}
}
func AirLine(){
let url = NSURL(string: "http://jsonplaceholder.typicode.com/posts")
NSURLSession.sharedSession().dataTaskWithURL(url!){[unowned self] (data , respnse , error) in
if error != nil{
print(error!)
}else{
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! [[String:AnyObject]]
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
var newPost = Iduser(id: 0)
for posts in json {
let postObj = Post(userid:posts["userId"] as! Int,title: posts["title"] as! String)
self.postCollection.append(postObj)
}
dispatch_async(dispatch_get_main_queue()){
self.tableView.reloadData()
}
}catch let error as NSError{
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
print(error.localizedDescription)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON:\(jsonStr)")
dispatch_async(dispatch_get_main_queue()) {
let alert = UIAlertController(title: "Alert", message: "Oops! Wrong Details, Try Again", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
}
}
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return self.postCollection.count ?? 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("AirCell", forIndexPath: indexPath)
// Configure the cell...
// cell.textLabel?.text = "test"
let weatherSummary = postCollection[indexPath.row]
cell.textLabel?.text = String(weatherSummary.userId)
cell.detailTextLabel?.text = weatherSummary.title
return cell
}
}
mainTableView and Air cell is Ok but when that selected other return The same information Air cell?
Perhaps I'm just missing it, but I can see your creation of the NSURLSession looks fine, but I don't see where you're calling .resume() on that once you've created it. If you don't call .resume() it'll never even perform that URLSession at all. Check the discussion here.

Resources