Add sections from a JSON file to a TableView - ios

Good morning, everyone,
I have created a TableView that uses data from a JSON file.
I can put my data in my TableView with Alamofire, but for ease of reference I would like to sort them by section with date.
Because for each date over 15 days there are weather forecasts for each hour.
So ideally I would like a section per day that opens with the click and gives every hour with forecasts.
This is my ViewController:
import UIKit
import Alamofire
import MapKit
class WeatherProController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource,UITableViewDelegate {
private let refreshControl = UIRefreshControl()
var datas = [WeatherProData]()
var locManager = CLLocationManager()
var currentLocation: CLLocation!
var timer = Timer()
var jour = UIColor(red: 0, green: 191 / 255, blue: 1, alpha: 1)
var nuit = UIColor(red: 51 / 255, green: 116 / 255, blue: 255 / 255, alpha: 1)
let didBecomeActiveNotificationName = UIApplication.didBecomeActiveNotification
let identifiantCell = "dataProCell"
let identifiantSegue = "versDetailDonneePro"
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var menuButton: UIBarButtonItem!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
locManager.requestAlwaysAuthorization()
NotificationCenter.default.addObserver(self, selector: #selector(scheduleTimer), name: didBecomeActiveNotificationName, object: nil)
changeBackground()
data()
// Add Refresh Control to Table View
if #available(iOS 10.0, *) {
tableView.refreshControl = refreshControl
} else {
tableView.addSubview(refreshControl)
}
// Configure Refresh Control
refreshControl.addTarget(self, action: #selector(refreshWeatherData(_:)), for: .valueChanged)
refreshControl.tintColor = UIColor.white
let attributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
refreshControl.attributedTitle = NSAttributedString(string: "Refreshing please wait", attributes: attributes)
}
#objc private func refreshWeatherData(_ sender: Any) {
fetchWeatherData()
}
private func setupActivityIndicatorView() {
activityIndicatorView.startAnimating()
}
private func fetchWeatherData() {
data()
self.refreshControl.endRefreshing()
// self.activityIndicatorView.stopAnimating()
}
#objc func scheduleTimer() {
// schedule the timer
timer = Timer(fireAt: Calendar.current.nextDate(after: Date(), matching: DateComponents(hour: 6..<21 ~= Date().hour ? 21 : 6), matchingPolicy: .nextTime)!, interval: 0, target: self, selector: #selector(changeBackground), userInfo: nil, repeats: false)
print(timer.fireDate)
// RunLoop.main.add(timer, forMode: .RunLoop.Mode.common)
print("new background chenge scheduled at:", timer.fireDate.description(with: .current))
}
#objc func changeBackground(){
// check if day or night shift
self.view.backgroundColor = 6..<21 ~= Date().hour ? jour : nuit
// schedule the timer
scheduleTimer()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return datas.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: identifiantCell) as? WeatherProCell {
let data = datas[indexPath.row]
cell.creerCell(data)
return cell
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? WeatherProCell {
cell.textIsHidden.isHidden = !cell.textIsHidden.isHidden
cell.textIsHidden1.isHidden = !cell.textIsHidden1.isHidden
cell.textIsHidden2.isHidden = !cell.textIsHidden2.isHidden
cell.textIsHidden3.isHidden = !cell.textIsHidden3.isHidden
cell.textIsHidden4.isHidden = !cell.textIsHidden4.isHidden
cell.textIsHidden5.isHidden = !cell.textIsHidden5.isHidden
cell.textIsHidden6.isHidden = !cell.textIsHidden6.isHidden
cell.textIsHidden7.isHidden = !cell.textIsHidden7.isHidden
cell.textIsHidden8.isHidden = !cell.textIsHidden8.isHidden
cell.textIsHidden9.isHidden = !cell.textIsHidden9.isHidden
cell.cloud.isHidden = !cell.cloud.isHidden
cell.rTemp.isHidden = !cell.rTemp.isHidden
cell.cloudBase.isHidden = !cell.cloudBase.isHidden
cell.dewp.isHidden = !cell.dewp.isHidden
cell.press.isHidden = !cell.press.isHidden
cell.pressIcon.isHidden = !cell.pressIcon.isHidden
cell.hydro.isHidden = !cell.hydro.isHidden
cell.hydroIcon.isHidden = !cell.hydroIcon.isHidden
cell.vent.isHidden = !cell.vent.isHidden
cell.ventIcon.isHidden = !cell.ventIcon.isHidden
cell.rainIcon.isHidden = !cell.rainIcon.isHidden
cell.rain.isHidden = !cell.rain.isHidden
cell.iso0.isHidden = !cell.iso0.isHidden
cell.freezeRain.isHidden = !cell.freezeRain.isHidden
cell.noSnow.isHidden = !cell.noSnow.isHidden
cell.snowUp.isHidden = !cell.snowUp.isHidden
cell.visibility.isHidden = !cell.visibility.isHidden
cell.snowProb.isHidden = !cell.snowProb.isHidden
tableView.beginUpdates()
tableView.endUpdates()
tableView.deselectRow(at: indexPath, animated: true)
}
}
//func numberOfSections(in tableView: UITableView) -> Int {
// return datas.count
//}
//func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
// return datas[section].date
//}
func data() {
if ( CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
CLLocationManager.authorizationStatus() == .authorizedAlways) {
currentLocation = locManager.location
}
var headers: HTTPHeaders = [
"Content-Type": "application/json"
]
let user = loginWeatherPro
let password = motDePasseWeatherPro
if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
headers[authorizationHeader.key] = authorizationHeader.value
}
let now = Date()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone.init(abbreviation: "UTC")
formatter.locale = Locale(identifier: "en_US_POSIX")
print(formatter.string(from: now))
let days = Calendar.current.date(byAdding: .day, value: 15, to: now)
let urlB = urlDeBaseWeatherPro
let locate = "locatedAt=\(currentLocation.coordinate.longitude),\(currentLocation.coordinate.latitude)"
let period = "&validPeriod=PT0S"
let validFrom = "&validFrom=\(formatter.string(from: now))"
let validUntil = "&validUntil=\(formatter.string(from: days!))"
let fields = "&fields=" + fieldsParameter
let url = urlB + locate + period + validFrom + validUntil + fields
print(url)
Alamofire.request(url, headers:headers).responseJSON{ response in
if let JSON = response.result.value as? [String: AnyObject] {
if let forecast = JSON ["forecasts"] as? NSArray {
for element in forecast {
if let dict = element as? [String: AnyObject],
let dates = dict ["validFrom"] as? String ,
let weatherCode = dict ["weatherCode"] as? Int ,
let weatherCodeString = weatherCodesTab[weatherCode],
let temp = dict ["airTemperatureInCelsius"] as? Double ,
let cloud = dict ["effectiveCloudCoverInPercent"] as? Double ,
let rtemp = dict ["feelsLikeTemperatureInCelsius"] as? Double ,
let cloudBase = dict ["cloudBaseHeightInMeter"] as? Double ,
let dewp = dict ["dewPointTemperatureInCelsius"] as? Double ,
let press = dict ["airPressureAtSeaLevelInHectoPascal"] as? Double ,
let hydro = dict ["relativeHumidityInPercent"] as? Double ,
let vent = dict ["windSpeedInKilometerPerHour"] as? Double ,
let rain = dict ["precipitationProbabilityInPercent"] as? Double ,
let iso0 = dict ["freezingLevelHeightInMeter"] as? Double ,
let freezeRain = dict ["freezingRainProbabilityInPercent"] as? Double ,
let noSnow = dict ["noSnowPossibleBelowHeightInMeter"] as? Double ,
let snowUp = dict ["snowCertainAboveHeightInMeter"] as? Double ,
let visibility = dict ["visibilityInMeter"] as? Double ,
let snowProd = dict ["snowfallProbabilityInPercent"] as? Double {
self.datas.append(WeatherProData(date: (DateHelper.obtenir.jourDeLaSemaineWeather(dates)!) + " " + DateHelper.obtenir.dateWeatherPro(dates)! + " à " + (DateHelper.obtenir.heures(dates)!), weatherCode: weatherCodeString, temp: temp, cloud: cloud, rtemp: rtemp, cloudBase: cloudBase, dewp: dewp, press: press, hydro: hydro, vent: vent, rain: rain, iso0: iso0, freezeRain: freezeRain, noSnow: noSnow, snowUp: snowUp, visibility: visibility, snowProb: snowProd))
//print(weatherCodeString)
self.tableView.reloadData()
}
}
}
}
}
}
}
The model:
import UIKit
class WeatherProData {
private var _date: String
private var _weatherCode: String
private var _temp: Double
private var _cloud: Double
private var _rTemp: Double
private var _cloudBase: Double
private var _dewp: Double
private var _press: Double
private var _hydro: Double
private var _vent: Double
private var _rain: Double
private var _iso0: Double
private var _freezeRain: Double
private var _noSnow: Double
private var _snowUp: Double
private var _visibility: Double
private var _snowProb: Double
var date: String {
return _date
}
var weatherCode: String {
return _weatherCode
}
var temp: Double {
return _temp
}
var cloud: Double {
return _cloud
}
var rtemp: Double {
return _rTemp
}
var cloudBase: Double {
return _cloudBase
}
var dewp: Double {
return _dewp
}
var press: Double {
return _press
}
var hydro: Double {
return _hydro
}
var vent: Double {
return _vent
}
var rain: Double {
return _rain
}
var iso0: Double {
return _iso0
}
var freezeRain: Double {
return _freezeRain
}
var noSnow: Double {
return _noSnow
}
var snowUp: Double {
return _snowUp
}
var visibility: Double {
return _visibility
}
var snowProb: Double {
return _snowProb
}
init(date: String, weatherCode: String, temp: Double, cloud: Double, rtemp: Double, cloudBase: Double, dewp: Double, press: Double, hydro: Double, vent: Double, rain: Double, iso0: Double, freezeRain: Double, noSnow: Double, snowUp: Double, visibility: Double, snowProb: Double) {
_date = date
_weatherCode = weatherCode
_temp = temp
_cloud = cloud
_rTemp = rtemp
_cloudBase = cloudBase
_dewp = dewp
_press = press
_hydro = hydro
_vent = vent
_rain = rain
_iso0 = iso0
_freezeRain = freezeRain
_noSnow = noSnow
_snowUp = snowUp
_visibility = visibility
_snowProb = snowProb
}
}
The cell:
import UIKit
class WeatherProCell: UITableViewCell {
#IBOutlet weak var date: UILabel!
#IBOutlet weak var temp: UILabel!
#IBOutlet weak var weatherCode: UILabel!
#IBOutlet weak var tempIcon: UIImageView!
#IBOutlet weak var textIsHidden: UILabel! {
didSet {
textIsHidden.isHidden = true
}
}
#IBOutlet weak var textIsHidden1: UILabel! {
didSet {
textIsHidden1.isHidden = true
}
}
#IBOutlet weak var textIsHidden2: UILabel! {
didSet {
textIsHidden2.isHidden = true
}
}
#IBOutlet weak var textIsHidden3: UILabel! {
didSet {
textIsHidden3.isHidden = true
}
}
#IBOutlet weak var textIsHidden4: UILabel! {
didSet {
textIsHidden4.isHidden = true
}
}
#IBOutlet weak var textIsHidden5: UILabel! {
didSet {
textIsHidden5.isHidden = true
}
}
#IBOutlet weak var textIsHidden6: UILabel! {
didSet {
textIsHidden6.isHidden = true
}
}
#IBOutlet weak var textIsHidden7: UILabel! {
didSet {
textIsHidden7.isHidden = true
}
}
#IBOutlet weak var textIsHidden8: UILabel! {
didSet {
textIsHidden8.isHidden = true
}
}
#IBOutlet weak var textIsHidden9: UILabel! {
didSet {
textIsHidden9.isHidden = true
}
}
#IBOutlet weak var cloud: UILabel! {
didSet {
cloud.isHidden = true
}
}
#IBOutlet weak var rTemp: UILabel! {
didSet {
rTemp.isHidden = true
}
}
#IBOutlet weak var cloudBase: UILabel! {
didSet {
cloudBase.isHidden = true
}
}
#IBOutlet weak var dewp: UILabel! {
didSet {
dewp.isHidden = true
}
}
#IBOutlet weak var press: UILabel! {
didSet {
press.isHidden = true
}
}
#IBOutlet weak var pressIcon: UIImageView! {
didSet {
pressIcon.isHidden = true
}
}
#IBOutlet weak var hydro: UILabel! {
didSet {
hydro.isHidden = true
}
}
#IBOutlet weak var hydroIcon: UIImageView! {
didSet {
hydroIcon.isHidden = true
}
}
#IBOutlet weak var vent: UILabel! {
didSet {
vent.isHidden = true
}
}
#IBOutlet weak var ventIcon: UIImageView! {
didSet {
ventIcon.isHidden = true
}
}
#IBOutlet weak var rainIcon: UIImageView! {
didSet {
rainIcon.isHidden = true
}
}
#IBOutlet weak var rain: UILabel! {
didSet {
rain.isHidden = true
}
}
#IBOutlet weak var iso0: UILabel! {
didSet {
iso0.isHidden = true
}
}
#IBOutlet weak var freezeRain: UILabel! {
didSet {
freezeRain.isHidden = true
}
}
#IBOutlet weak var noSnow: UILabel! {
didSet {
noSnow.isHidden = true
}
}
#IBOutlet weak var snowUp: UILabel! {
didSet {
snowUp.isHidden = true
}
}
#IBOutlet weak var visibility: UILabel! {
didSet {
visibility.isHidden = true
}
}
#IBOutlet weak var snowProb: UILabel! {
didSet {
snowProb.isHidden = true
}
}
var data: WeatherProData!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func creerCell(_ data: WeatherProData) {
self.data = data
let attributedDate = NSMutableAttributedString(string: self.data.date)
date.attributedText = attributedDate
let Cloud = "\(self.data.cloud)" + " %"
cloud.text = Cloud
let Rtemp = "\(self.data.rtemp)" + " °C"
rTemp.text = Rtemp
let CloudBase = "\(self.data.cloudBase)" + " m"
cloudBase.text = CloudBase
let Dewp = "\(self.data.dewp)" + " °C"
dewp.text = Dewp
let Temp = "\(self.data.temp)" + " °C"
temp.text = Temp
tempIcon.image = #imageLiteral(resourceName: "Termometre")
let WeatherCode = "\(self.data.weatherCode)"
weatherCode.text = WeatherCode
let Press = "\(self.data.press)" + " hpa"
press.text = Press
pressIcon.image = #imageLiteral(resourceName: "Barometre")
let Hydro = "\(self.data.hydro)" + " %"
hydro.text = Hydro
hydroIcon.image = #imageLiteral(resourceName: "Hydrometrie")
let Vent = "\(self.data.vent)" + " km/h"
vent.text = Vent
ventIcon.image = #imageLiteral(resourceName: "Vent")
let Rain = "\(self.data.rain)" + " %"
rain.text = Rain
rainIcon.image = #imageLiteral(resourceName: "Pluviometre")
let Iso0 = "\(self.data.iso0)" + " m"
iso0.text = Iso0
let FreezeRain = "\(self.data.freezeRain)" + " %"
freezeRain.text = FreezeRain
let NoSnow = "\(self.data.noSnow)" + " m"
noSnow.text = NoSnow
let SnowUp = "\(self.data.snowUp)" + " m"
snowUp.text = SnowUp
let Visibility = "\(self.data.visibility)" + " m"
visibility.text = Visibility
let SnowProb = "\(self.data.snowProb)" + " %"
snowProb.text = SnowProb
}
}
I thank you in advance for your help because I have been fighting with this for 1 month
Here is the link to my GitHub to get the complete file:
https://github.com/superdevil669/MeteoWapi_iOS_App/tree/beta

One way would be to modify your data model having an array holding the dates (the values for the sections) and a dictionary holding an array of the weather values for each date.
For the sake of simplicity I have 'simulated' this with String as data type.
// Declaration Data model
var sections = [Date]()
var datas = [Date:[String]]()
// Some test values to show how the processing could be
let date = Date()
let value = "Test"
// This would be inside your processing loop
// Check, if section already exists
if !sections.contains(date)
{
// Add date to sections array
sections.append(date)
// Insert empty array in datas dictionary
datas[date] = [String]()
}
// Add value to array
datas[date]?.append(value)
// This could be inside cellForRowAtIndexPath
// Fetch value
let indexPath = IndexPath(row: 0, section: 0)
let value2 = datas[sections[indexPath.section]]?[indexPath.row]

First of all private backing variables to get constants is horrible in Swift. You can declare constants simply with the let keyword.
If you use a struct you can even reduce WeatherProData to
struct WeatherProData {
let date: String // must be `Date` for smart grouping
let weatherCode: String
let temp: Double
let cloud: Double
let rTemp: Double
let cloudBase: Double
let dewp: Double
let press: Double
let hydro: Double
let vent: Double
let rain: Double
let iso0: Double
let freezeRain: Double
let noSnow: Double
let snowUp: Double
let visibility: Double
let snowProb: Double
}
because you get the init method for free
Grouping an array is very easy in Swift. The suggestion below assumes that date is declared and decoded as Date.
Dictionary(grouping:by: groups the array by the condition in the closure in this case midnight of the current date.
let calendar = Calendar.current
let grouped = Dictionary(grouping: datas, by: { calendar.startOfDay(for: $0.date) })
print(grouped)
And in Swift 4.2+ you can negate a boolean with
cell.textIsHidden.isHidden.toggle()
Consider also to use the Deodable protocol to get rid of the manual decoding.

I tried another project so as not to damage mine.
import UIKit
import Alamofire
struct WeatherProData {
let date: String // must be `Date` for smart grouping
// let weatherCode: String
// let temp: Double
// let cloud: Doublea
// let rTemp: Double
// let cloudBase: Double
// let dewp: Double
// let press: Double
// let hydro: Double
// let vent: Double
// let rain: Double
// let iso0: Double
// let freezeRain: Double
// let noSnow: Double
// let snowUp: Double
// let visibility: Double
// let snowProb: Double
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var data = [WeatherProData]()
var sections = [Date]()
var dataT = [Date:[String]]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
let date = Date()
let value = "Test"
if !sections.contains(date) {
sections.append(date)
dataT[date] = [String]()
}
dataT[date]?.append(value)
var headers : HTTPHeaders = ["Content-Type":"application.json"]
// Ajout lofin et mot de passe pour la connection à weather pro
let user = loginWeatherPro
let password = motDePasseWeatherPro
// Ajout de l'autorisation de connection
if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
headers[authorizationHeader.key] = authorizationHeader.value
}
// formattage de l'heure
let now = Date()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone.init(abbreviation: "UTC")
formatter.locale = Locale(identifier: "en_US_POSIX")
print(formatter.string(from: now))
let days = Calendar.current.date(byAdding: .day, value: 1, to: now)
// preparation de l'url de base
let urlB = urlDeBaseWeatherPro
let locate = "locatedAt=3.284752,50.644164"
let period = "&validPeriod=PT0S"
let validFrom = "&validFrom=\(formatter.string(from: now))"
let validUntil = "&validUntil=\(formatter.string(from: days!))"
let fields = "&fields=" + fieldsParameter
let url = urlB + locate + period + validFrom + validUntil + fields
Alamofire.request(url, headers:headers).responseJSON { response in
if let JSON = response.result.value as? [String: AnyObject] {
if let forecast = JSON ["forecasts"] as? NSArray {
for element in forecast {
if let dict = element as? [String: AnyObject],
let dates = dict ["validFrom"] as? String {
self.data.append(WeatherProData(date: dates))
print(dates)
self.tableView.reloadData()
}
}
}
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return dataT.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "test"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let datas = data[indexPath.row]
cell.textLabel?.text = datas.date
return cell
}
override func viewWillAppear(_ animated: Bool) {
self.tableView.reloadData()
}
}
I did the simplest thing, but I can't classify my UITableView not section I think it must be due to the JSON file that sends me this as date.
2019-01-14T10:34:04Z
2019-01-14T12:00:00+01:00
2019-01-14T13:00:00+01:00
2019-01-14T14:00:00+01:00
2019-01-14T15:00:00+01:00
2019-01-14T16:00:00+01:00
2019-01-14T17:00:00+01:00
2019-01-14T18:00:00+01:00
2019-01-14T19:00:00+01:00
2019-01-14T20:00:00+01:00
2019-01-14T21:00:00+01:00
2019-01-14T22:00:00+01:00
2019-01-14T23:00:00+01:00
2019-01-15T00:00:00+01:00
2019-01-15T01:00:00+01:00
2019-01-15T02:00:00+01:00
2019-01-15T03:00:00+01:00
2019-01-15T04:00:00+01:00
2019-01-15T05:00:00+01:00
2019-01-15T06:00:00+01:00
2019-01-15T07:00:00+01:00
2019-01-15T08:00:00+01:00
2019-01-15T09:00:00+01:00
2019-01-15T10:00:00+01:00
2019-01-15T11:00:00+01:00
Thank you. Thank you.

I'm still trying. I can create my sections but I can't display them without the hours.
I would like each section to have the title of the day, and below that the hours of each day.
import UIKit
import Alamofire
struct WeatherProData {
let date: String // must be `Date` for smart grouping
// let weatherCode: String
// let temp: Double
// let cloud: Doublea
// let rTemp: Double
// let cloudBase: Double
// let dewp: Double
// let press: Double
// let hydro: Double
// let vent: Double
// let rain: Double
// let iso0: Double
// let freezeRain: Double
// let noSnow: Double
// let snowUp: Double
// let visibility: Double
// let snowProb: Double
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#objc func refresh(_ sender: Any) {
// Call webservice here after reload tableview.
tableView.reloadData()
refreshControl.endRefreshing()
}
var data = [WeatherProData]()
var sections = [String]()
var dateSection = [[WeatherProData]]()
var refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// RefrechControl sur UITableVIew
refreshControl.attributedTitle = NSAttributedString(string: "Tirez pour rafraichir")
refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
self.tableView.addSubview(refreshControl)
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
var headers : HTTPHeaders = ["Content-Type":"application.json"]
// Ajout lofin et mot de passe pour la connection à weather pro
let user = loginWeatherPro
let password = motDePasseWeatherPro
// Ajout de l'autorisation de connection
if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
headers[authorizationHeader.key] = authorizationHeader.value
}
// formattage de l'heure
let now = Date()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone.init(abbreviation: "UTC")
formatter.locale = Locale(identifier: "en_US_POSIX")
print(formatter.string(from: now))
let days = Calendar.current.date(byAdding: .day, value: 1, to: now)
let french = DateFormatter()
french.dateStyle = .full
french.dateFormat = "dd MMMM"
french.locale = Locale(identifier: "FR_fr")
print(french.string(from: now))
// preparation de l'url de base
let urlB = urlDeBaseWeatherPro
let locate = "locatedAt=3.284752,50.644164"
let period = "&validPeriod=PT0S"
let validFrom = "&validFrom=\(formatter.string(from: now))"
let validUntil = "&validUntil=\(formatter.string(from: days!))"
let fields = "&fields=" + fieldsParameter
let url = urlB + locate + period + validFrom + validUntil + fields
Alamofire.request(url, headers:headers).responseJSON { response in
if let JSON = response.result.value as? [String: Any] {
if let forecast = JSON ["forecasts"] as? NSArray {
for element in forecast {
if let dict = element as? [String: Any],
let dates = dict ["validFrom"] as? String {
self.data.append(WeatherProData(date: dates))
self.sections = Array(Set(self.data.map({ (WeatherProData) -> String in
WeatherProData.date
})))
self.sections.forEach({ (string) in self.dateSection.append([])})
for index in 0..<self.sections.count {
self.data.forEach({ (data) in
if data.date == self.sections[index] {
self.dateSection[index].append(data)
}
})
}
self.tableView.reloadData()
}
}
}
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
for index in 0..<sections.count {
if index == section {
return dateSection[index].count
}
}
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
// let datas = data[indexPath.row]
cell.textLabel?.text = dateSection[indexPath.section] [indexPath.row].date
// cell.textLabel?.text = datas.date
self.tableView.addSubview(self.refreshControl)
return cell
}
}
This is what I get.
My UITableView

In
self.sections = Array(Set(self.data.map({ (WeatherProData) -> String in
WeatherProData.date
})))
, when you have -> String means that the function is asking you to return a string value. So you need to add a return with the string value in your code.
Here is a working code for your situation :
self.sections = Array(Set(self.data.map({ (WeatherProData) -> String in
let jsonDateString = WeatherProData.date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXX"
if let weatherProDataDate = dateFormatter.date(from: jsonDateString) {
return french.string(from: weatherProDataDate)
} else {
return ""
}
})))

Related

Tableview array is not loaded properly in iOS Swift?

I'm working in a chat application. Saving sender and receiver messages to firebase. My issue when tried to load array message to TableView, messages are not completely loaded. it shows gap for remaining messages.
MainChatViewController.swift
var messages = [Message]()
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("message count::\(messages.count)")
let message = messages[indexPath.row]
if let cell = chatTableView.dequeueReusableCell(withIdentifier: "Message") as? mainChatScreenTableViewCell {
cell.tag = indexPath.row
cell.configCell(message: message)
return cell
} else {
return mainChatScreenTableViewCell()
}
}
func loadData() {
Database.database().reference().child("messages").child(messageId)
.observe(.value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
self.messages.removeAll()
for data in snapshot {
if let postDict = data.value as? Dictionary<String, AnyObject>
{
let key = data.key
let post = Message(messageKey: key, postData: postDict)
self.messages.append(post)
}
}
}
self.chatTableView.reloadData()
})
}//loadData
func moveToBottom() {
DispatchQueue.main.async {
if self.messages.count > 0 {
let indexPath = IndexPath(row: self.messages.count - 1, section: 0)
self.chatTableView.scrollToRow(at: indexPath, at: .bottom, animated: false)
}
}
}
mainChatScreenTableViewCell
import UIKit
import SwiftKeychainWrapper
import Firebase
import FirebaseStorage
import FirebaseDatabase
class mainChatScreenTableViewCell: UITableViewCell {
#IBOutlet weak var recievedMessageLbl: UILabel!
#IBOutlet weak var recievedMessageView: UIView!
#IBOutlet weak var sentMessageLbl: UILabel!
#IBOutlet weak var sentMessageView: UIView!
#IBOutlet var receivedTimeLabel: UILabel!
#IBOutlet var sentTimeLabel: UILabel!
#IBOutlet var likeOrUnlikeImageView: UIImageView!
#IBOutlet var errorImageView: UIImageView!
#IBOutlet var checkImage: UIImageView!
var message: Message!
var currentUser = KeychainWrapper.standard.string(forKey: "uid")
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
sentMessageView.layer.masksToBounds = true
recievedMessageView.layer.masksToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func configCell(message: Message) {
self.message = message
print("message label::\(message.message.count)")
if message.sender == currentUser {
let time = message.receivedTimeStamp
let timeinterval : TimeInterval = time
let dateFromServer = NSDate(timeIntervalSince1970:timeinterval)
let formatter = DateFormatter()
formatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.ISO8601) as Calendar?
formatter.locale = NSLocale(localeIdentifier: "en_IN") as Locale
formatter.timeZone = NSTimeZone(name: "GMT+5:30") as TimeZone?
formatter.dateFormat = "h:mm a"
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
let dateString: String = formatter.string(from: dateFromServer as Date)
print("dateString:::\(dateString)")
sentMessageView.isHidden = false
sentMessageView.layer.backgroundColor = UIColor.clear.cgColor
sentMessageLbl.text = " " + message.message
sentTimeLabel.text = " " + dateString
recievedMessageLbl.text = ""
recievedMessageLbl.isHidden = true
recievedMessageView.isHidden = true
} else {
let time = message.receivedTimeStamp
let timeinterval : TimeInterval = time
let dateFromServer = NSDate(timeIntervalSince1970:timeinterval)
let formatter = DateFormatter()
formatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.ISO8601) as Calendar?
formatter.locale = NSLocale(localeIdentifier: "en_IN") as Locale
formatter.timeZone = NSTimeZone(name: "GMT+5:30") as TimeZone?
formatter.dateFormat = "h:mm a"
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
let dateString: String = formatter.string(from: dateFromServer as Date)
print("dateString:::\(dateString)")
sentMessageView.isHidden = true
sentMessageLbl.isHidden = true
sentMessageLbl.text = ""
recievedMessageLbl.text = " " + message.message
receivedTimeLabel.text = " " + dateString
recievedMessageLbl.isHidden = false
recievedMessageView.layer.backgroundColor = UIColor.clear.cgColor
}
}
}
Here is my screenshot:
I'm getting correct message count but messages are fully loaded.
Any help much appreciated pls...
use it. heightForRowAt for height of cell but you must check your constraint.
and also use UITableViewDelegate to use it
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}

iOS / Swift - Appending a filter to retrieving data from Firebase

What I got so far is a tableView and custom Cells about hookah tobacco. Those include an image, name, brand and ID. Now what I try to reach is basically a tableview that contains only the cells with attributes based on a "filter". For example the tableView that appears at the beginning has only the following two settings to make it simple: PriceRange and BrandName. At the first time loading the tableView those are PriceRange: 0 - 100 and Brands: all brands. Then imagine a user restricting those like 0 - 15 Euros and only brand called "7 Days". How exactly would I do that with reloading the tableView?
import UIKit
import Firebase
class ShopViewController: UIViewController, UISearchBarDelegate {
#IBOutlet weak var button_filter: UIBarButtonItem!
#IBOutlet weak var searchBar_shop: UISearchBar!
#IBOutlet weak var view_navigator: UIView!
#IBOutlet weak var tableView_shop: UITableView!
var ShopCells: [ShopCell] = []
var databaseRef: DatabaseReference!
var storageRef: StorageReference!
override func viewDidLoad() {
super.viewDidLoad()
self.databaseRef = Database.database().reference()
self.storageRef = Storage.storage().reference()
createArray() { shopCells in
for item in shopCells {
self.ShopCells.append(item)
}
DispatchQueue.main.async {
self.tableView_shop.reloadData()
}
}
self.navigationItem.title = "Shop"
self.tableView_shop.delegate = self
self.tableView_shop.dataSource = self
self.searchBar_shop.delegate = self
self.searchBar_shop.barTintColor = UIColor(hexString: "#1ABC9C")
self.view_navigator.backgroundColor = UIColor(hexString: "#1ABC9C")
self.tableView_shop.separatorColor = UIColor.clear
self.searchBar_shop.isTranslucent = false
self.searchBar_shop.backgroundImage = UIImage()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ShopViewController.viewTapped(gestureRecognizer:)))
view.addGestureRecognizer(tapGesture)
}
#objc func viewTapped(gestureRecognizer: UITapGestureRecognizer) {
view.endEditing(true)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.searchBar_shop.resignFirstResponder()
}
func createArray(completion: #escaping ([ShopCell]) -> () ) {
var tempShopCells: [ShopCell] = []
let rootRef = Database.database().reference()
let query = rootRef.child("tobaccos").queryOrdered(byChild: "name")
query.observeSingleEvent(of: .value) { (snapshot) in
let dispatchGroup = DispatchGroup()
for child in snapshot.children.allObjects as! [DataSnapshot] {
let value = child.value as? [String: Any];
let name = value?["name"] as? String ?? "";
let brand = value?["brand"] as? String ?? "";
let iD = value?["iD"] as? String ?? "";
dispatchGroup.enter()
let imageReference = Storage.storage().reference().child("tobaccoPictures").child("\(iD).jpg")
imageReference.getData(maxSize: (1 * 1024 * 1024)) { (data, error) in
if let _error = error{
print(_error)
} else {
if let _data = data {
let image: UIImage! = UIImage(data: _data)
tempShopCells.append(ShopCell(productName: name, brandName: brand, productImage: image, iD: iD))
}
}
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main) {
completion(tempShopCells)
}
}
}
}
extension ShopViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.ShopCells.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let shopCell = ShopCells[indexPath.row]
let cell = tableView_shop.dequeueReusableCell(withIdentifier: "ShopCell") as! ShopTableViewCell
cell.setShopCell(shopCell: shopCell)
return cell
}
}

Parsing json data through alamofire in table view cells

I am trying to parse json data in my table view cell and its not parsing and not showing the cells . I am attaching all my code please tell me whats the mistake i am doing .. I am not getting any error but the cells are not showing. I have made separate class and functions for json parsing and storing it in an array .
//
// ViewController.swift
// WorkingFeed2
//
// Created by keshu rai on 08/08/17.
// Copyright © 2017 keshu rai. All rights reserved.
//
import UIKit
import Alamofire
import MediaPlayer
class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource{
var post : PostData!
var posts = [PostData]()
typealias DownloadComplete = () -> ()
var arrayOfPostData : [String] = []
#IBOutlet weak var feedTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
feedTable.dataSource = self
feedTable.delegate = self
}
func downloadPostData(completed: #escaping DownloadComplete) {
Alamofire.request("https://new.example.com/api/posts/get_all_posts").responseJSON { response in
let result = response.result
if let dict = result.value as? Dictionary<String,AnyObject> {
if let successcode = dict["STATUS_CODE"] as? Int {
if successcode == 1 {
if let postsArray = dict["posts"] as? [Dictionary<String,AnyObject>]
{
for obj in postsArray
{
let post = PostData(postDict: obj)
self.posts.append(post)
print(obj)
}
// self.posts.remove(at: 0)
self.feedTable.reloadData()
}
}
}
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 419
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : ImageTableViewCell = self.feedTable.dequeueReusableCell(withIdentifier: "contentViewReuse") as! ImageTableViewCell
let post = posts[indexPath.row]
print(post)
cell.configureCell(post : post)
return cell
}
}
This is my PostData Class.
import Foundation
class PostData {
var _profileImageURL : String?
var _fullName : String?
var _location : String?
var _title : String?
var _postTime : String?
var _likes : Int?
var _comments : Int?
var _mediaType : String?
var _contentURL : String?
var _content : String?
var _plocation : String?
var profileImageURL : String
{
if _profileImageURL == nil {
_profileImageURL = ""
}
return _profileImageURL!
}
var fullName : String
{
if _fullName == nil {
_fullName = ""
}
return _fullName!
}
var location : String {
if _location == nil {
_location = ""
}
return _location!
}
var title : String {
if _title == nil {
_title = ""
}
return _title!
}
var postTime : String {
if _postTime == nil {
_postTime = ""
}
return _postTime!
}
var likes : Int {
if _likes == nil {
_likes = 0
}
return _likes!
}
var comments : Int {
if _comments == nil {
_comments = 0
}
return _comments!
}
var mediaType : String {
if _mediaType == nil {
_mediaType = ""
}
return _mediaType!
}
var contentURL : String {
if _contentURL == nil {
_contentURL = ""
}
return _contentURL!
}
var content : String {
if _content == nil {
_content = ""
}
return _content!
}
var pLocation : String {
if _plocation == nil {
_plocation = ""
}
return _plocation!
}
init(postDict : Dictionary<String , AnyObject>)
{
if let postsArray = postDict["posts"] as? [Dictionary<String,AnyObject>]
{
for i in 1..<postsArray.count
{
let fullName1 = postsArray[i]["full_name"] as? String
self._fullName = fullName1
let profileImageURL1 = postsArray[i]["profile_pic"] as? String
self._profileImageURL = profileImageURL1
let location1 = postsArray[i]["user_city"] as? String
self._location = location1
let title1 = postsArray[i]["title"] as? String
self._title = title1
let postTime1 = postsArray[i]["order_by_date"] as? String
self._postTime = postTime1
let likes1 = postsArray[i]["liked_count"] as? Int
self._likes = likes1
let comments1 = postsArray[i]["comment_count"] as? Int
self._comments = comments1
let mediaType1 = postsArray[i]["media_path"] as? String
self._mediaType = mediaType1
let contentURL1 = postsArray[i]["media_path"] as? String
self._contentURL = contentURL1
let content1 = postsArray[i]["content"] as? String
self._content = content1
let plocation1 = postsArray[i]["location"] as? String
self._plocation = plocation1
}
}
}
}
This is my PostDataTableViewCell code.
import UIKit
import Alamofire
class PostDataTableViewCell: UITableViewCell {
#IBOutlet weak var profileImage: UIImageView!
#IBOutlet weak var titlePost: UILabel!
#IBOutlet weak var profileFullName: UILabel!
#IBOutlet weak var profileUserLocation: UILabel!
#IBOutlet weak var likeBtn: UIButton!
var buttonAction: ( () -> Void) = {}
var pressed = false
#IBAction func likeBtnPressed(_ sender: Any) {
if !pressed {
let image = UIImage(named: "Like-1.png") as UIImage!
likeBtn.setImage(image, for: .normal)
pressed = true
} else {
let image = UIImage(named: "liked.png") as UIImage!
likeBtn.transform = CGAffineTransform(scaleX: 0.15, y: 0.15)
UIView.animate(withDuration: 2.0,
delay: 0,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 6.0,
options: .allowUserInteraction,
animations: { [weak self] in
self?.likeBtn.transform = .identity
},
completion: nil)
likeBtn.setImage(image, for: .normal)
pressed = false
}
}
#IBAction func commentBtnPressed(_ sender: Any) {
print("Commented")
}
#IBAction func shareBtnPressed(_ sender: Any) {
self.buttonAction()
}
#IBAction func readContentBtnPressed(_ sender: Any) {
print("Read")
}
#IBOutlet weak var contentPostLabel: UILabel!
#IBOutlet weak var contentTypeView: UIView!
#IBOutlet weak var likeAndCommentView: UIView!
#IBOutlet weak var numberOfLikes: UILabel!
#IBOutlet weak var numberOfComments: UILabel!
#IBOutlet weak var postLocation: UILabel!
#IBOutlet weak var postTimeOutlet: UILabel!
func configureCell(post : PostData)
{
titlePost.text = "\(post.title)"
profileFullName.text = "\(post.fullName)"
profileUserLocation.text = "\(post.location)"
numberOfLikes.text = "\(post.likes) Likes"
numberOfComments.text = "\(post.comments) Comments"
postLocation.text = "\(post.pLocation)"
postTimeOutlet.text = "\(post.postTime)"
let url = URL(string: post.profileImageURL)
let data = try? Data(contentsOf: url!)
profileImage.image = UIImage(data: data!)
contentPostLabel.text = "\(post.content)"
if post.mediaType == "image"
{
let url1 = URL(string: post.contentURL)
let data1 = try? Data(contentsOf: url1!)
let image = UIImage(data: data1!)
let imageToView = UIImageView(image: image!)
imageToView.frame = CGRect(x: 0, y: 0, width: 375 , height: 250)
imageToView.contentMode = UIViewContentMode.scaleToFill
contentTypeView.addSubview(imageToView)
}
else if post.mediaType == "null"
{
print("Status")
}
else if post.mediaType == "video"
{
print("Video")
}
else if post.mediaType == "youtube"
{
print("youtube")
}
}
}
Most likely the issue occurs because you are trying to parse the value for key posts twice, once in PostData and once in ViewController.
First of all in Swift 3 a JSON dictionary is [String:Any], secondly – as already mentioned in my comment – private backing variables are nonsense in Swift.
The class PostData can be reduced to
class PostData {
let profileImageURL : String
let fullName : String
let location : String
let title : String
let postTime : String
let likes : Int
let comments : Int
let mediaType : String
let contentURL : String
let content : String
let plocation : String
init(postDict : [String:Any])
{
fullName = postDict["full_name"] as? String ?? ""
profileImageURL = postDict["profile_pic"] as? String ?? ""
location = postDict["user_city"] as? String ?? ""
title = postDict["title"] as? String ?? ""
postTime = postDict["order_by_date"] as? String ?? ""
likes = postDict["liked_count"] as? Int ?? 0
comments = postDict["comment_count"] as? Int ?? 0
mediaType = postDict["media_path"] as? String ?? ""
contentURL = postDict["media_path"] as? String ?? ""
content = postDict["content"] as? String ?? ""
plocation = postDict["location"] as? String ?? ""
}
}

Accessing struct object array in no of rows in section returning null

I am trying to download data and put it in struct objects and trying to load data in table view .I am downloading it in to array and append it to struct object.when I am taking return array.count in no of rows in section its working when I use return objectArray[section].funcName.count its not working values are getting late to download also
import UIKit
import Alamofire
class GalleryVC: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var galleryTable: UITableView!
var imageUrlArray:[String] = [String]()
var imageCount:[String] = [String]()
var funName1:[String] = [String]()
var gaimage1:String = ""
var gacount1:String = ""
var funname1:String = ""
struct Objects {
var imageName : [String]!
var imageCount : [String]!
var funcName:[String]!
}
var objectArray = [Objects]()
var objectArrayFilter = [Objects]()
var inSearchMode = false
override func viewDidLoad() {
super.viewDidLoad()
downloadGalleryList()
galleryTable.delegate = self
galleryTable.dataSource = self
searchBar.delegate = self
self.hideKeyboardWhenTappedAround()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
print(objectArray[section].funcName.count)
return objectArray[section].funcName.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier:"gallerycell", for: indexPath) as? GalleryListCell{
if inSearchMode{
cell.galleryImage.sd_setImage(with: URL(string: objectArrayFilter[indexPath.section].imageName[indexPath.row]), placeholderImage: UIImage(named: "1862205"))
cell.galleryphotono.text = objectArrayFilter[indexPath.section].imageCount[indexPath.row]+" photos"
cell.galleryFunction.text = objectArrayFilter[indexPath.section].funcName[indexPath.row]
return cell
}
cell.galleryImage.sd_setImage(with: URL(string: objectArray[indexPath.section].imageName[indexPath.row]), placeholderImage: UIImage(named: "1862205"))
cell.galleryphotono.text = objectArray[indexPath.section].imageCount[indexPath.row]+" photos"
cell.galleryFunction.text = objectArray[indexPath.section].funcName[indexPath.row]
return cell
}
else{
return UITableViewCell()
}
}
func downloadGalleryList(){
let bmiChapterUrl = URL(string:Gallery_List)!
Alamofire.request(bmiChapterUrl).responseJSON{ response in
let result = response.result
print(response)
print(result)
if let dict = result.value as? Dictionary<String,AnyObject>{
if let bmi = dict["result"] as? [Dictionary<String,AnyObject>]
{
for obj in bmi {
if let gaimage = obj["image"] as? String
{
print(gaimage)
self.gaimage1 = gaimage
self.imageUrlArray.append(gaimage)
}
if let gacount = obj["count"] as? String
{
self.gacount1 = gacount
print(gacount)
self.imageCount.append(gacount)
}
if let funname = obj["event"] as? String
{
print(funname)
self.funname1 = funname
self.funName1.append(funname)
}
}
}
}
print(self.imageUrlArray,self.imageCount,self.funName1
)
self.objectArray.append(Objects(imageName: self.imageUrlArray, imageCount:self.imageCount,funcName: self.funName1))
print(self.objectArray)
self.galleryTable.reloadData()
}
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
inSearchMode = false
view.endEditing(true)
galleryTable.reloadData()
} else {
inSearchMode = true
objectArrayFilter = objectArray.filter { $0.imageName.contains(where: { $0.contains(searchBar.text!) }) }
print(objectArrayFilter)
galleryTable.reloadData()
}
}
}

Value missing after swipe gesture

I have a problem with a swipe gesture. I insert the NSUserdefaults function, but it doesn't work. Whenever I swipe, the value (you can see 90 at the pic) is always missing whenever I swipe it back.
The code that I insert NSUserdefaults looks like this:
This is the table controller, which shows the JSON data:
struct JSONActivity
{
static var jsondata = ""
}
class TableControllerActivities: UITableViewController {
var items = NSMutableArray()
var TableData:Array< String > = Array < String >()
var json:String = ""
#IBOutlet var myTableView: UITableView!
var arrayOfMenu: [Activity] = [Activity]()
#IBAction func setting(sender: AnyObject) {
self.performSegueWithIdentifier("SettingView", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.setUpMenu()
self.myTableView.delegate = self
self.myTableView.dataSource = self
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOfMenu.count //hitung banyak data pada array
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//fungsi agar json dapat membaca tiap row pada storyboard
var shortDate: String {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM"
return dateFormatter.stringFromDate(NSDate())
}
let cell: CustomCellActivity = tableView.dequeueReusableCellWithIdentifier("cell") as! CustomCellActivity
let menu = arrayOfMenu[indexPath.row]
cell.setCell(menu.type, rightlabeltext: menu.unit, imagename: menu.image)
//memasukkan data ke json, misal textbox isi 3 maka akan diwrite ke json 3
var data = Activitiesdata(type: menu.type, amount: String(cell.value).toInt()!)
var json = JSONSerializer.toJson(data)
JSONActivity.jsondata = json
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func do_table_refresh()//mengapdet / merefresh data
{
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
return
})
}
func setUpMenu() //membaca json pada setiap arraynya
{
var json: JSON = JSON (data: NSData())
let frame:CGRect = CGRect(x: 110, y: 300, width: view.frame.width, height: 700)
self.tableView.frame = frame
DataManager.getactivityDataFromFileWithSuccess{ (data) -> Void in
json = JSON(data: data)
let results = json["results"]
for (index: String, subJson: JSON) in results {
}
for (var i = 0; i < json["Activity"].count; i++) {
if let type = json["Activity"][i]["type"].string {
//println("Tipe : \(type)")
if let icon: AnyObject = json["Activity"][i]["icon"].string {
self.items.addObject(icon)
if let unit_id = json["Activity"][i]["unit_id"].string {
//println("Logo : \(unit_id)")
dispatch_async(dispatch_get_main_queue(), {self.tableView!.reloadData()})
var menu = Activity(type: type, unit: unit_id, image: icon as! String)
self.arrayOfMenu.append(menu)
self.TableData.append(type + unit_id )
self.do_table_refresh()
}
}
}
}
}
}
}
And this is the cell controller, where the value is incremented:
struct Activitymenu
{
static var dataact:Array<String> = Array <String>()
static var quantity = ""
}
class CustomCellActivity: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var leftlabel: UILabel!
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var rightlabel: UILabel!
#IBOutlet weak var qtytext: UITextField!
#IBOutlet weak var decrease: UIImageView!
var value = 0
var checks:Bool = false
var dx = 0
override func awakeFromNib() {
super.awakeFromNib()
self.myImageView.userInteractionEnabled = true
self.decrease.userInteractionEnabled = true
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
qtytext.resignFirstResponder()
self.endEditing(true)
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch: UITouch? = touches.first as? UITouch
if(touch?.view == myImageView)
{
value += 30
qtytext.text = String(value)
println(qtytext.text)
}
if(touch?.view == decrease)
{
if(value >= 30)
{
value -= 30;
println(qtytext.text)
}
}
qtytext.resignFirstResponder()//respon pada editing textbox
self.endEditing(true)
qtytext.delegate = self
qtytext.text = String(value)
let myquantity = qtytext.text
NSUserDefaults.standardUserDefaults().setObject(myquantity, forKey: "SavedStringKey")
NSUserDefaults.standardUserDefaults().synchronize()
let stringKey = NSUserDefaults.standardUserDefaults()
qtytext.text = stringKey.stringForKey("SavedStringKey")
var data = Activitiesdata(type: leftlabel.text!, amount: qtytext.text.toInt()!)
var temp:Activitiesdata
temp = data
var idx = 0
if(temp.amount-30 > 0) {
temp.amount -= 30
}
data = Activitiesdata(type: leftlabel.text!, amount: qtytext.text.toInt()!)
var json = JSONSerializer.toJson(data)
var tempJson = JSONSerializer.toJson(temp)
for(var i = 0; i < Activitymenu.dataact.count; i++){
if(Activitymenu.dataact[i] == tempJson){
self.checks = true
self.dx = i
}
}
if(!self.checks) {
Activitymenu.dataact.append(json)
}
else{
Activitymenu.dataact[self.dx] = json
}
}
func setCell(leftlabeltext: String, rightlabeltext: String, imagename: String)
{
self.leftlabel.text = leftlabeltext
self.rightlabel.text = rightlabeltext
self.myImageView.image = UIImage(named: imagename)
}
}
I think, the value is still there, but it not shown, why is that?
myquantity, value and qty text have the same output of 90..3.

Resources