I was trying to get swfityjson and almo to work in Xcode 8
like in the post in this page:
Showing JSON data on TableView using SwiftyJSON and Alamofire
But I can not get the data from the self.
This helped me a little, but I am stuck with the count. Someone please help me with this, beacuse I am new to swift and have spent the day trying to understand how to get the count of rows and the data out of the almo function.
import UIKit
import Alamofire
import SwiftyJSON
class TableViewController: UITableViewController {
var names = [String]()
var rowCount = [Int]()
var tableTitle = [String]()
typealias JSONStandard = [String : AnyObject]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func callAlamo(){
let url = "http://xxxxxx/xxxx/xxxxxx.php"
//let id = UserDefaults.standard.string(forKey: "UserDefaults")
Alamofire.request(url).responseJSON{(respones)->Void in
if let value = respones.result.value{
let json = JSON(value)
let rows = json["items"].arrayValue
for anItem in rows {
let title: String? = anItem["SupplierName"].stringValue
self.tableTitle.append(title!)
//print(self.tableTitle.count)
}
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(_ animated: Bool) {
// let isUserLoggedin = UserDefaults.standard.boll(forKey: "userLogIn")
let ststus = UserDefaults.standard.string(forKey: "userLogIn")
if ststus == "false" {
self.performSegue(withIdentifier: "loginView", sender: self)
}else{
callAlamo()
}
}
#IBAction func logout(_ sender: AnyObject) {
UserDefaults.standard.set(false, forKey: "userLogIn")
UserDefaults.standard.synchronize()
self.performSegue(withIdentifier: "loginView", sender: self)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print (tableTitle)
return self.tableTitle.count
}
}
I am unable to get the tableTitle.count. Thanks!
UITableView Delegate methods are called before viewDidAppear. So you need to reload the UITableView after got the response from server
DispatchQueue.main.async {
self.tableView.reloadData()
}
After the for loop.
import UIKit
import Alamofire
import SwiftyJSON
class TableViewController: UITableViewController {
var names = [String]()
var rowCount = [Int]()
var tableTitle = [String]()
typealias JSONStandard = [String : AnyObject]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func callAlamo(){
let url = "http://pos1.dermedia.co.il/iphone/getLasttransactions.php?cardid="
//let id = UserDefaults.standard.string(forKey: "UserDefaults")
Alamofire.request(url).responseJSON{(respones)->Void in
if let value = respones.result.value{
let json = JSON(value)
// print (json["items"].arrayValue)
let rows = json["items"].arrayValue
// print (rows)
for anItem in rows {
let title: String? = anItem["SupplierName"].stringValue
self.tableTitle.append(title!)
print(self.tableTitle.count)
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(_ animated: Bool) {
// let isUserLoggedin = UserDefaults.standard.boll(forKey: "userLogIn")
let ststus = UserDefaults.standard.string(forKey: "userLogIn")
if ststus == "false" {
self.performSegue(withIdentifier: "loginView", sender: self)
}else{
callAlamo()
print ("gggggg")
print(self.tableTitle.count)
}
}
#IBAction func logout(_ sender: AnyObject) {
UserDefaults.standard.set(false, forKey: "userLogIn")
UserDefaults.standard.synchronize()
self.performSegue(withIdentifier: "loginView", sender: self)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print (self.tableTitle)
print("hhh")
return tableTitle.count
}
}
Related
I am using firebase when I follow user his post show up nicely in the UITableView . but when unfollow him , his post still in the UITableView. UITableView not reloading data after unfollow.
View Controller :
import UIKit
import SVProgressHUD
import SDWebImage
class HomeVC: UIViewController {
#IBOutlet weak var tableViewOutLet: UITableView!
#IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
var postContentArray = [Post]() // contine all Posts .
var userContentArray = [UserModel]()
override func viewDidLoad() {
super.viewDidLoad()
tableViewOutLet.dataSource = self
tableViewOutLet.estimatedRowHeight = 521
tableViewOutLet.rowHeight = UITableView.automaticDimension
loadPosts()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.isHidden = false
}
#objc func loadPosts () {
// activityIndicatorView.startAnimating()
API.Feed.ObserveFeedWithMyPostAndFollowerPost(withid: API.User.Curren_User!.uid) { (postr) in
self.fetchUserInfo(PostUserID: postr.userPostId!, Completed: {
self.postContentArray.append(postr)
// self.activityIndicatorView.stopAnimating()
self.tableViewOutLet.reloadData()
})
}
API.Feed.ObserveFeedReomved(withid: API.User.Curren_User!.uid) { (key) in
// print(key)
self.postContentArray = self.postContentArray.filter {$0.userPostId != key }
self.tableViewOutLet.reloadData()
}
}
#objc func fetchUserInfo (PostUserID : String , Completed : #escaping ()-> Void) {
API.User.observeUserInformation(CommentUserID: PostUserID) { (User) in
self.userContentArray.append(User)
Completed()
}
}
#IBAction func logOutButton(_ sender: Any) {
AuthServices.logout(OnSuccess: {
SVProgressHUD.showSuccess(withStatus: "تم تسجيل الخروج")
let storyBoard = UIStoryboard(name: "Start", bundle: nil)
let signInvc = storyBoard.instantiateViewController(withIdentifier: "SignInVC")
self.present(signInvc, animated: true, completion: nil)
}) { (error) in
SVProgressHUD.showError(withStatus: error)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "commentIconSequeToCommentPage" {
let commentvc = segue.destination as! CommentsVC
commentvc.postID = sender as? String
}
}
}
extension HomeVC: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postContentArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as! HomeTableViewCell
let postContent = postContentArray[indexPath.row]
let userContent = userContentArray[indexPath.row]
cell.postContent = postContent
cell.userContentInfo = userContent
cell.homeView = self
return cell
}
}
Observe Functions :
import Foundation
import FirebaseDatabase
class FeedAPI {
var REF_FEED = Database.database().reference().child("Feed")
func ObserveFeedWithMyPostAndFollowerPost (withid id : String , complation : #escaping (Post)->Void) {
REF_FEED.child(id).observe(DataEventType.childAdded) { (snapshto : DataSnapshot) in
let key = snapshto.key
API.Post.observePostFuntion(withID: key, Complation: { (post) in
complation(post)
})
}
}
func ObserveFeedReomved (withid id : String , complation : #escaping (String)->Void) {
REF_FEED.child(id).observe(DataEventType.childRemoved) { (snapshot : DataSnapshot) in
let key = snapshot.key
complation(key)
}
}
}
where exactly is the unfollow function?
Also you should set the tableview delegate
override func viewDidLoad() {
tableViewOutLet.delegate = self
}
Please show where exactly are you preforming the unfollow function.
my follow And unfollow func
class FollowAPI {
var REF_FOLLOWERS = Database.database().reference().child("Follower")
var REF_FOLLOWING = Database.database().reference().child("Following")
func followAction (withId id : String) {
API.Follow.REF_FOLLOWERS.child(id).child(API.User.Curren_User!.uid).setValue(true)
API.Follow.REF_FOLLOWING.child(API.User.Curren_User!.uid).child(id).setValue(true)
API.myPOSTS.REF_MYPOSTS.child(id).observeSingleEvent(of: DataEventType.value) { (snapshot : DataSnapshot) in
print(snapshot.key)
if let dic = snapshot.value as? [String : Any]{
for key in dic.keys {
API.Feed.REF_FEED.child(API.User.Curren_User!.uid).child(key).setValue(true)
}
}
}
}
func UnFollowAction (withid id : String) {
API.Follow.REF_FOLLOWERS.child(id).child(API.User.Curren_User!.uid).setValue(NSNull())
API.Follow.REF_FOLLOWING.child(API.User.Curren_User!.uid).child(id).setValue(NSNull())
API.myPOSTS.REF_MYPOSTS.child(id).observeSingleEvent(of: DataEventType.value) { (snapshot : DataSnapshot) in
print(snapshot.key)
if let dic = snapshot.value as? [String : Any]{
for key in dic.keys {
API.Feed.REF_FEED.child(API.User.Curren_User!.uid).child(key).removeValue()
}
}
}
}
func isFollwoing (userid : String , Complated : #escaping (Bool)->Void) {
REF_FOLLOWERS.child(userid).child(API.User.Curren_User!.uid).observeSingleEvent(of: .value) { (snapshot ) in
if let _ = snapshot.value as? NSNull {
Complated(false)
} else {
Complated(true)
}
}
}
}
I am a beginner to Xcode and Swift and I am currently creating an application where the user adds a person on the application and after that it right the amount of money they owe that person or that person owes him/her.
Note: I have used core data to store all the value
I actually want to change the value of a variable when switch is on and off. For instance, in the following I want the "amount" to be negative when the switch is on and positive when it is off. Also, when I try to do this and send amount variable to previous view controller I can't send the value depending on the UISwitch because it always shows positive. I am trying to find a solution to this from past 3 days therefore can you please help me? Thanks a lot in advance
Owe ViewController
import UIKit
class NewOweTableViewController: UIViewController {
#IBOutlet weak var titleTextField: UITextField!
#IBOutlet weak var locationTextField: UITextField!
#IBOutlet weak var amountTextField: UITextField!
#IBOutlet weak var datePicker: UIDatePicker!
let context = (UIApplication.shared.delegate as!
AppDelegate).persistentContainer.viewContext
var owe: Owe?
var dataInfo: [Owe] = []
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.viewWithTag(1)?.isHidden = true
let saveBTN = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.save, target:self,
action: #selector(saveButtonTapped(_:)))
let deleteBTN = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.trash, target:self,
action: #selector(deleteButtonTapped(_:)))
self.navigationItem.rightBarButtonItems = [saveBTN, deleteBTN]
if !dataInfo.isEmpty {
titleTextField.text = dataInfo[0].name
amountTextField.text = (NSString(format: "%.2f", (dataInfo[0].amount) as CVarArg) as String)
locationTextField.text = dataInfo[0].location
datePicker.date = dataInfo[0].date!
}
}
#objc func saveButtonTapped(_ sender: UIButton){
if !dataInfo.isEmpty{
let data = dataInfo[0]
data.name = titleTextField.text
data.amount = Double(amountTextField.text!)!
data.location = locationTextField.text
data.date = datePicker.date
}
else if titleTextField.text == "" || amountTextField.text == "" || locationTextField.text == "" {
return
}
else{
let data = Owe(context: context)
data.name = titleTextField.text
data.amount = Double(amountTextField.text!)!
data.location = locationTextField.text
data.date = datePicker.date
}
do {
try context.save()
navigationController?.popViewController(animated: true)
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
#objc func deleteButtonTapped(_ sender: UIButton){
if !dataInfo.isEmpty{
let data = dataInfo[0]
context.delete(data)
do {
try context.save()
navigationController?.popViewController(animated: true)
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
#IBAction func oweSwitch(_ sender: UISwitch) {
if sender.isOn {
owe?.amount = (owe?.amount)! * (-1)
amountTextField.textColor = UIColor.green
} else {
owe?.amount = (owe?.amount)! * (1)
amountTextField.textColor = UIColor.red
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Previous View Controller
import UIKit
class PersonDetailTableViewController: UITableViewController {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var totalLabel: UILabel?
var person: People?
var owe: Owe?
#IBOutlet var personTable: UITableView!
var dataInfo: [Owe] = []
var selectedObject: [Owe] = []
var balanceAmount = "Balance: "
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (dataInfo.count)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = personTable
.dequeueReusableCell(withIdentifier: "detailsCell", for: indexPath)
cell.textLabel?.text = dataInfo[indexPath.row].name
cell.detailTextLabel?.text = "₹ \(dataInfo[indexPath.row].amount)"
if dataInfo[indexPath.row].amount < 0 {
cell.detailTextLabel?.textColor = UIColor.red
} else {
cell.detailTextLabel?.textColor = UIColor.green
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedObject = [dataInfo[indexPath.row]]
performSegue(withIdentifier: "addOweDetails", sender: nil)
tableView.deselectRow(at: indexPath, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
getData()
personTable.dataSource = self
addTotalToNav()
print(dataInfo as Any)
}
// MARK: - Table view data source
func addTotalToNav() -> Void {
if let navigationBar = self.navigationController?.navigationBar {
let totalFrame = CGRect(x: 10, y: 0, width: navigationBar.frame.width/2, height: navigationBar.frame.height)
totalLabel = UILabel(frame: totalFrame)
totalLabel?.text = balanceAmount
totalLabel?.tag = 1
totalLabel?.font = UIFont.boldSystemFont(ofSize: 14)
totalLabel?.textColor = UIColor.red
// navigationBar.large = totalLabel?.text
self.title = totalLabel?.text
}
}
func getData() -> Void {
do{
dataInfo = try context.fetch(Owe.fetchRequest())
var total:Double = 0.00
for i in 0 ..< dataInfo.count {
total += dataInfo[i].amount as! Double
}
balanceAmount = "Balance: ₹" + (NSString(format: "%.2f", total as CVarArg) as String)
}
catch{
print("Fetching Failed")
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! NewOweTableViewController
vc.dataInfo = selectedObject
selectedObject.removeAll()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getData()
personTable.reloadData()
if (self.navigationController?.navigationBar.viewWithTag(1)?.isHidden == true){
self.navigationController?.navigationBar.viewWithTag(1)?.removeFromSuperview()
addTotalToNav()
}
}
}
Core Data for owe
import UIKit
import CoreData
#objc(Owe)
public class Owe: NSManagedObject {
var date: Date? {
get{
return rawDate as Date?
}
set {
rawDate = newValue as NSDate?
}
}
convenience init?(name: String?, location: String?, amount: Double, date: Date?) {
let appDelegate = UIApplication.shared.delegate as? AppDelegate
guard let context = appDelegate?.persistentContainer.viewContext
else {
return nil
}
self.init(entity: Owe.entity(), insertInto: context)
self.name = name
self.location = location
self.amount = amount
self.date = date
}
}
Hi there and welcome to the Swift Community!
If I understand correctly, you are trying to propagates updates backwards from NewOweTableViewController to PersonDetailTableViewController. If that is the case, an easy way to achieve this with your MVC architecture is by passing a closure to NewOweTableViewController when you initialize it in PersonDetailTableViewController.
In order to do so,
Update NewOweTableViewController and add a closure property.
class NewOweTableViewController: UIViewController {
// ...
var switchValueUpdate: ((Bool) -> ())?
// ...
}
Make sure you call this closure inside your #IBAction that you link to your switch in NewOweTableViewController
#IBAction func oweSwitch(_ sender: UISwitch) {
if sender.isOn {
owe?.amount = (owe?.amount)! * (-1)
amountTextField.textColor = UIColor.green
} else {
owe?.amount = (owe?.amount)! * (1)
amountTextField.textColor = UIColor.red
}
switchValueUpdate?(sender.isOn)
}
update PersonDetailTableViewController to set the closure
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! NewOweTableViewController
vc.dataInfo = selectedObject
selectedObject.removeAll()
vc.switchValueUpdate = { (isOn) in
// Here you go, update PersonDetailTableViewController to reflect changes related to the switch!
}
}
That's it! Let me know if you have any question on that code, hope it helps!
I am doing in mvvm method.my code as below.
foodModel :-
class foodModel: NSObject {
var name :String!
var city :String!
var imageurl :String!
init?(dictionary :JSONDictionary) {
guard let name = dictionary["name"] as? String,
let imageurl = dictionary["imageurl"] as? String,
let city = dictionary["city"] as? String else {
return
}
self.name = name
self.city = city
self.imageurl = imageurl
}
}
foodDataSourceModel:-
class foodDataSourceModel: NSObject {
var dataListArray:Array<foodModel>? = []
init(array :Array<[String:Any]>?) {
super.init()
var newArray:Array<[String:Any]> = []
if array == nil{
newArray = self.getJsonDataStored1()
}
else{
newArray = array!
}
var datalist:Array<foodModel> = []
for dict in newArray{
let model = foodModel(dictionary: dict)
datalist.append(model!)
}
self.dataListArray = datalist
}
}
typealias dummyDataSource1 = foodDataSourceModel
extension dummyDataSource1{
func getJsonDataStored1() ->Array<Dictionary<String,String>>{
let jsonArray = [["name":"Anjapar","imageurl":"","city":"india"],["name":"Anjapar","imageurl":"","city":"india"]] as Array<Dictionary<String,String>>
return jsonArray
}
}
foodViewModel:-
class foodViewModel: NSObject {
var datasourceModel:foodDataSourceModel
init(withdatasource newDatasourceModel:foodDataSourceModel) {
datasourceModel = newDatasourceModel
}
func datafordisplay(atindex index: Int) -> foodModel {
return datasourceModel.dataListArray![index]
}
func numberOfItemsInSection(section:Int) -> Int {
return (datasourceModel.dataListArray?.count)!
}
func loadData(){
loadFromWebserviceData { (newDataSourceModel) in
self.datasourceModel = newDataSourceModel!
}
}
func loadFromWebserviceData(completion :#escaping (foodDataSourceModel?) -> ()){
let url = URL(string :"http://example.com")!
URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data {
let json = try! JSONSerialization.jsonObject(with: data, options: [])
//let dictionaries = json as! [JSONDictionary]
let array = json as! Array<[String:Any]>
let newDataSource:foodDataSourceModel = foodDataSourceModel(array: array)
// DispatchQueue.main.async {
//
// }
completion(newDataSource)
}
}.resume()
}
}
foodViewController:-
#IBOutlet private weak var tableView: UITableView!
private var foodViewModel :foodViewModel!
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?, withViewModel viewModel:foodViewModel) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
foodViewModel = viewModel
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
// tableView.register(UINib(nibName: "foodCell", bundle: nil), forCellReuseIdentifier: "cell")
foodViewModel.loadData()
self.tableView .reloadData()
// Do any additional setup after loading the view.
}
// func numberOfSections(in tableView: UITableView) -> Int {
// return restaurtantViewModel.numberOfItemsInSection(section: Int)
// }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell")! as! foodCell
//cell.setRestaurtantData(restaurtant: foodModel)
cell.textLabel?.text = "rtyuiop"
//
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
}
*/
}
foodCell:-
class foodCell: UITableViewCell {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var city: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func setRestaurtantData(restaurtant:foodModel)
{
self.name.text = restaurtant.name
self.city.text = restaurtant.city
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Here output is not getting .I need to display the values in tableview.Showing an error as failed to obtain a cell from dataSource
{
"query": "sandwich",
"results_count": 12,
"page": 1,
"results": [
{
"name": "Caffè Macs",
"coordinates": {
"lat": 37.330576,
"lng": -122.029739
},
"meals": ["breakfast", "lunch", "dinner"]
},
...
]
}
This is the pattern ,so from this i need to get the values as "name","lng" and "lat".
There is some problem in load the data from Json .In the urlsession task -showing as variable not available. please check .How to solve this?
Please update your viewDidLoad(). You must set delegate and datasource of tableview.
First set in class:-
class yourClass: UIViewController,UITableViewDelegate , UITableViewDataSource
Now
override func viewDidLoad() {
super.viewDidLoad()
// tableView.register(UINib(nibName: "foodCell", bundle: nil), forCellReuseIdentifier: "cell")
foodViewModel.loadData()
self.tableView .delegate = self
self.tableview.dataSource = self
self.tableView .reloadData()
When you fetch data from a web service, this is usually done in a asynchronous manner. In your viewDidLoad method, you're updating your table view immediately after the call which starts fetching the data.
override func viewDidLoad() {
...
// Start fetching the data
foodViewModel.loadData()
// Reloading the table view even though the data might not be ready
self.tableView.reloadData()
...
}
You can fix this by passing a callback to your loadData function in your foodViewModel:
func loadData(completion: (() -> ()) {
loadFromWebserviceData { (newDataSourceModel) in
self.datasourceModel = newDataSourceModel!
completion()
}
}
And in your foodViewController, you would then wait to update your table view until the data source is ready to be displayed:
override func viewDidLoad() {
...
foodViewModel.loadData {
self.tableView.reloadData()
}
...
}
While the code above should work, this is just to highlight the problem you're currently facing and therefore, was kept as simple as possible.
I created a UIViewController class with a tableView to show different places in the cells, i'm working with Alamofire and Google API (maps, places), the only problem is that when i run the project the cells are empty, this is my controller class:
import UIKit
class SelectClass: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var list : [QCategoryy] = [QCategoryy]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
self.title = "Categories"
list = NearbyPlaces.getCategories()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
list.sort() { $0.views > $1.views}
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func backTapp(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func doneTapp(_ sender: Any) {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "CATEGORY_CELL"
let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
cell.textLabel?.text = list[indexPath.row].name
return cell
}
let nearbySearchSegueIdentifier = "goToMcourse"
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: nearbySearchSegueIdentifier, sender: list[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == nearbySearchSegueIdentifier {
guard let category = sender as? QCategoryy else {
return
}
if let vc = segue.destination as? CourseClass2 {
vc.category = category
}
}
}
}
extension QCategoryy {
private static let ketPrefix = "category-"
var views:Int {
get {
return UserDefaults.standard.integer(forKey: QCategoryy.ketPrefix + name)
}
}
func markView() {
UserDefaults.standard.set(views + 1, forKey: QCategoryy.ketPrefix + name)
}
}
and these are the two classes that work with it:
import Foundation
import UIKit
import CoreLocation
import Alamofire
class NearbyPlaces {
static func getCategories() -> [QCategoryy] {
let list:[QCategoryy] = ["Bakery", "Doctor", "School", "Taxi_stand", "Hair_care", "Restaurant", "Pharmacy", "Atm", "Gym", "Store", "Spa"]
return list
}
static let searchApiHost = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"
static let googlePhotosHost = "https://maps.googleapis.com/maps/api/place/photo"
static func getNearbyPlaces(by category:String, coordinates:CLLocationCoordinate2D, radius:Int, token: String?, completion: #escaping (QNearbyPlacesResponse?, Error?) -> Void) {
var params : [String : Any]
if let t = token {
params = [
"key" : AppDelegate.googlePlacesAPIKey,
"pagetoken" : t,
]
} else {
params = [
"key" : AppDelegate.googlePlacesAPIKey,
"radius" : radius,
"location" : "\(coordinates.latitude),\(coordinates.longitude)",
"type" : category.lowercased()
]
}
Alamofire.request(searchApiHost, parameters: params, encoding: URLEncoding(destination: .queryString)).responseJSON { response in
if let error = response.error {
completion(nil, error)
}
if let response = QNearbyPlacesResponse(dic : response.result.value as? [String : Any]) {
completion(response, nil)
}
else {
completion(nil, QNearbyPlacesResponseError.noParsingDone)
}
}
}
static func googlePhotoURL(photoReference:String, maxWidth:Int) -> URL? {
return URL.init(string: "\(googlePhotosHost)?maxwidth=\(maxWidth)&key=\(AppDelegate.googlePlacesAPIKey)&photoreference=\(photoReference)")
}
}
enum QNearbyPlacesResponseError : Error {
case noParsingDone
}
struct QNearbyPlacesResponse {
var nextPageToken: String?
var status: String = "NOK"
var places: [QPlace]?
init?(dic:[String : Any]?) {
nextPageToken = dic?["next_page_token"] as? String
if let status = dic?["status"] as? String {
self.status = status
}
if let results = dic?["results"] as? [[String : Any]]{
var places = [QPlace]()
for place in results {
places.append(QPlace.init(placeInfo: place))
}
self.places = places
}
}
func canLoadMore() -> Bool {
if status == "OK" && nextPageToken != nil && nextPageToken?.characters.count ?? 0 > 0 {
return true
}
return false
}
}
and
struct QCategoryy {
var name:String
init(name:String) {
self.name = name
}
}
extension QCategoryy: ExpressibleByStringLiteral {
init(stringLiteral value: String) {
self.name = value
}
init(unicodeScalarLiteral value: String) {
self.init(name: value)
}
init(extendedGraphemeClusterLiteral value: String) {
self.init(name: value)
}
}
it seems to me that it's all right, i can not understand why when i go into my uiviewcontroller the tableView has all the empty cells, here there is also a screen of what i see when running the project
hope someone can find the issue
Try with:
tableView.dataSource = self
Try adding:
tableView.dataSource = self
tableView.delegate = self`
to your viewDidLoad()
I try to pass data from my ViewController to TableViewPlace.swiftUse the buttons. When I am choosing button return not some thing
viViewController
class ViewController: UIViewController {
struct Country{
var id :Int
init(id:Int){
self.id = id
}
}
var CountrySelected = [Country]()
var countryArry = NSArray()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func airAction(sender: AnyObject) {
}
#IBAction func viewPlaceAction(sender: AnyObject) {
getParsePlaceView()
// json viewPlace
performSegueWithIdentifier("viewPlaceSegu", sender: sender)
}
#IBAction func tourAction(sender: AnyObject) {
}
/// Open the page
// parse json
func getParsePlaceView(){
let url = NSURL(string: "http://jsonplaceholder.typicode.com/posts")
NSURLSession.sharedSession().dataTaskWithURL(url!){ [unowned self] (data , repsonse , error) in
if error != nil {
print(error!)
} else {
do {
let posts = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers) as! [[String:AnyObject]]
for post in posts {
if let id = post["userId"] as? Int{
// print(id)
let sets = Country(id: id)
self.CountrySelected.append(sets)
}
}
self.countryArry = posts
print(self.countryArry)// return data and currect
} catch let error as NSError {
print(error)
}
}
}.resume()
print(countryArry) // return nil why??
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// get a reference to the second view controller
if segue.identifier == "viewPlaceSegu" {
if let secondViewController = segue.destinationViewController as? TableViewPlace {
// set a variable in the second view controller with the String to pass
print(countryArry)
secondViewController.tnt = countryArry
}
}
}
}
when I print(countryArry) return nil why ??
Can someone help me or give me a better solution?
You are creating a Post object with this line :
let countryPlace = Post(userid: post["userId"] as! Int, title: post["title"] as! String)
And you are trying to pass to your tableview this Post object to your tnt variable which is a ViewController class, this is why you've got the first error :
secondViewController.tnt = Country
Then, if you want to add your string country to your mutable array you have to do :
if let title = tnt.title {
Country.append(title)
}