I am getting JSON data from an url like this:
...
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("jsonCell") as! CeldaGeo
var dict = arrRes[indexPath.row]
cell.cofradia.text = dict["cofradia"] as? String
cell.calle.text = dict["calle"] as? String
cell.id.text = dict["idc"] as? String
cell.tipo.text = dict["tipo"] as? String
cell.latitud.text = dict["latitud"] as? String
cell.longitud.text = dict["longitud"] as? String
cell.tipo.text = dict["tipo"] as? String
let tipo = dict["tipo"] as? String
let id = dict["idc"] as? String
cell.imagen.kf_setImageWithURL(NSURL(string: "http://elpenitente.playcofrade.com/img/escudos/\(tipovalue)/\(id!).jpg")!)
return cell
After, I load an image from an url which changes depending the other values.
My problem is, the value tipois a number (1,2,3) but in the url it should be text. For example 1 will be cofradias. How can I assign this values so that I can use them later?
If I understood your problem correctely. You only need to have a separate dictionary mapping the ids with its strings.
let imageNames = ["1":"cofradias","2":"string2","3":"string3"]
Then in your code you'll use it like:
let id = dict["idc"] as? String
let tipo = dict["tipo"] as? String
let imageName = imageNames[tipo!]
cell.imagen.kf_setImageWithURL(NSURL(string: "http://elpenitente.playcofrade.com/img/escudos/cofradias/\(imageName!)/\(id!).jpg")!)
Related
I made a struct dictionary to get the user title and URL, and then I store them on the phone but when I come to retrieve the data in cellForRow method the cell label is empty, what should appear is the title.(tableView starts off empty until user starts to populate it with the AddArticle action)
So my question is if I'm doing it right because the cell label just turns out nil?
Struct Dictionary:
struct AddMagazine {
let rssUrl: String
let title: String
init(dict: [String : String]){
title = dict["title"] ?? ""
rssUrl = dict["rssUrl"] ?? ""
}
}
var userMagazineTitle = [AddMagazine]()
Getting values from textField:
#IBAction func AddArticle(_ sender: Any) {
animateIn()
tableView.isScrollEnabled = false
}
func addArticleTitle() {
let UserMagazines = AddMagazine.init(dict: ["title": RssTitle.text!, "rssUrl": RssText.text!])
let storedRssUrl = UserMagazines.rssUrl
self.dataString = storedRssUrl
//setting
defaults.set(dataString, forKey: "storedArray")
userMagazineTitle.append(UserMagazines)
tableView.reloadData()
}
Trying to retrieve title here:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyFeedTableViewCell
let headlineName = defaults.object(forKey: "storedArray") as? AddMagazine
cell.myHeadline.text = headlineName?.title
cell.indentationLevel = 3
return cell
}
You’re storing a String object in defaults for “storedArray” but then you typecast it to an AddMagazine when you read it from defaults. Change what you store or read it as a string.
I agree with #Joakim Danielson. You are storing storedRssUrl which is a string into userdefaults and while retrieving you are type casting as AddMagazine hence it will be nil.
self.dataString = storedRssUrl
//setting
defaults.set(dataString, forKey: "storedArray") --> Here you are storing string
let headlineName = defaults.object(forKey: "storedArray") as? AddMagazine --> Here you are fetching as AddMagazine.
//It should be like this
let headlineName = defaults.object(forKey: "storedArray") as? String
Here I am having Json data which I am retrieving from model class in which I need to find if the key value pair title having word starting with Discount for example if I find key value pair starting with Discount I need to set the particular table view cell label as Discount how to find it from key value pairs can anyone help me how to implement this ?
Here is my model class data
struct TotalPriceSegments {
let code : String?
let title : String?
let value : Double?
init(json: [String:Any]) {
self.code = json["code"] as? String
self.title = json["title"] as? String
self.value = json["value"] as? Double
}
}
Here is table view code
let cell = tableView.dequeueReusableCell(withIdentifier: "checkout", for: indexPath) as! CheckoutTableViewCell
let array = totalPriceModel?.totalSegments[indexPath.row]
cell.titleLabel.text = array?.title
let total = doubleToStringDecimalPlacesWithDouble(number: Double((array?.value)!), numberOfDecimalPlaces: 2)
cell.valueLabel.text = (String(describing:("$ \(total)")))
return cell
In cellForRow method add such check:
if array?.title.hasPrefix("Discount") {
cell.titleLabel.text = "Discount"
}
I am using firebase to load data into tableview cells, and here is the structure of my data.
struct postStruct {
let title : String!
let author : String!
let bookRefCode : String!
let imageDownloadString : String!
let status : String!
let reserved : String!
let category : String!
let dueDate : String!
}
Now I have the posts sorted alphabetically using
self.posts.sort(by: { $0.title < $1.title })
but I do not know how to place the cells that start with A in a section "A", and "B", and so on.
class DirectoryTableView: UITableViewController {
var posts = [postStruct]()
override func viewDidLoad() {
let databaseRef = Database.database().reference()
databaseRef.child("Books").queryOrderedByKey().observe(.childAdded, with: {
snapshot in
var snapshotValue = snapshot.value as? NSDictionary
let title = snapshotValue!["title"] as? String
snapshotValue = snapshot.value as? NSDictionary
let author = snapshotValue!["author"] as? String
snapshotValue = snapshot.value as? NSDictionary
let bookRefCode = snapshotValue!["bookRefCode"] as? String
snapshotValue = snapshot.value as? NSDictionary
let status = snapshotValue!["status"] as? String
snapshotValue = snapshot.value as? NSDictionary
let reserved = snapshotValue!["reserved"] as? String
snapshotValue = snapshot.value as? NSDictionary
let category = snapshotValue!["category"] as? String
snapshotValue = snapshot.value as? NSDictionary
let dueDate = snapshotValue!["dueDate"] as? String
snapshotValue = snapshot.value as? NSDictionary
self.posts.insert(postStruct(title: title, author: author, bookRefCode: bookRefCode, status: status, reserved: reserved, category: category, dueDate: dueDate) , at: 0)
self.tableView.reloadData()
})
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let databaseRef = Database.database().reference()
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = posts[indexPath.row].title
let label2 = cell?.viewWithTag(2) as! UILabel
label2.text = posts[indexPath.row].author
let label3 = cell?.viewWithTag(3) as! UILabel
label3.text = posts[indexPath.row].bookRefCode
let label4 = cell?.viewWithTag(4) as! UILabel
label4.text = posts[indexPath.row].status
let label5 = cell?.viewWithTag(5) as! UILabel
label5.text = posts[indexPath.row].category
let image1 = cell?.viewWithTag(6) as! UILabel
image1.text = posts[indexPath.row].imageDownloadString
let label6 = cell?.viewWithTag(7) as! UILabel
label6.text = posts[indexPath.row].reserved
let label9 = cell?.viewWithTag(9) as! UILabel
label9.text = posts[indexPath.row].dueDate
return cell!
}
Any ideas, please help! I have tried to sort them with different methods, but I'm confused!
First, you'll need a new structure to save your posts grouped by it's first title letter: let postsAlphabetically: [String:[Post]]
You didn't specify the Swift version, so assuming you'll migrate to Swift 4, you can sort the data and group it using a single line:
let postsAlphabetically = Dictionary(grouping: self.posts) { $0.title.first! }
// E.g: ["A" : ["A book", "Another book"], "B" : ["Blue Book", "Black Book"]]
Later on, you'll use postsAlphabetically instead of self.posts in your cellForRowAt method.
P.S: Type names in Swift are written in upper camel case (PostSimple not postSimple). And the type itself is omitted (Author instead of AuthorClass).
I am having trouble with an array that it is filled correctly in a separated function, the issue is when i try to fill in the elements of my cell in my tableview, i can only find the last element however when i want to display the number of elements in that array while filling the cell it displays the correct number of elements, can anybody help please.
this is my function for retrieving and filling in the array:
func downloadUserDetails(completed: #escaping DownloadComplete){
let Ful_Url = "http://192.168.1.4:8888/phps/select.php"
Alamofire.request(Ful_Url).responseJSON(completionHandler: { (response) in
if let userDect = response.result.value as? [Dictionary<String,AnyObject>]{
for ex in 0...userDect.count-1
{
if let firstnames = userDect[ex]["firstname"] as? String{
self.users?.firstname = firstnames}
if let emails = userDect[ex]["email"] as? String{
self.users?.email = emails}
if let lastnames = userDect[ex]["lastname"] as? String{
self.users?.lastname = lastnames}
print("---------------------------------")
self.items.append(self.users!)
// self.items.insert(self.users!, at: self.i)
print(self.items[ex].email)
print(self.items.count)
}
}
completed()
self.tableview.reloadData()
})
}
this is how i am trying to fill the cell's labels:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("####################")
print("nombre items")
print(self.items.count)
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier:"myCell" , for:indexPath)
let email:UILabel = cell.viewWithTag(11) as! UILabel
let firstname:UILabel = cell.viewWithTag(12) as! UILabel
let lastname:UILabel = cell.viewWithTag(13) as! UILabel
print("=========================email=========================")
print(items[indexPath.row].email)
email.text = items[indexPath.row].email
firstname.text = items[indexPath.row].firstname
lastname.text = items[indexPath.row].lastname
return cell
}
I think trouble in insert method:
self.item.insert(self.users!, at:self,i);
You can try :
self.item.insert(self.users!, at:ex);
I think that your issue is that you are using one single instance of user and then appending it to the array, Each item in the array points to the same item (classes are passed by reference).
You do not need to do this, you dont need to maintain a count or index during iteration either.
This code should work fine..
if let usersDict = response.result.value as? [Dictionary<String,AnyObject>] {
self.users = usersDict.map({ dict in
let user = User()
if let firstnames = dict["firstname"] as? String{
user.firstname = firstnames }
if let emails = dict["email"] as? String{
user.email = emails }
if let lastnames = dict["lastname"] as? String{
user.lastname = lastnames }
return user
})
self.tableView.reloadData()
}
Or even better, allow your User object to be intialised with a dictionary and then do
if let usersDict = response.result.value as? [Dictionary<String,AnyObject>] {
self.users = usersDict.map({ User($0) })
self.tableView.reloadData()
}
Just use local variables during your loop, no need for class properties here. To use the bottom one, you will need to be able to initialise the User object with a dictionary. Similar to this method:
struct User
{
var firstName:String
var lastName:String
var email:String
init(dict:Dictionary<String,AnyObject>) {
email = dict["email"] as? String
firstName = dict["firstName"] as! String
lastName = dict["lastName"] as! String
}
}
UPDATE:
I just wrote this in a playground which works fine
class User {
var firstName: String!
var lastName: String!
var email: String!
init(dict: [String:AnyObject]) {
self.firstName = dict["firstName"] as! String
self.lastName = dict["lastName"] as! String
self.email = dict["email"] as! String
}
}
let usersDict: [[String:String]] = [
["firstName": "John", "lastName": "Smith", "email": "john#example.com"],
["firstName": "John", "lastName": "Smithy", "email": "john#example.com"],
["firstName": "John", "lastName": "Stevens", "email": "john#example.com"],
["firstName": "John", "lastName": "Smithen", "email": "john#example.com"]
]
let users = usersDict.map({ User(dict: $0 as! [String : AnyObject]) })
for user in users {
print(user.firstName, user.lastName)
}
Output:
John Smith
John Smithy
John Stevens
John Smithen
Actually i have just found the solution for any one who faces the same problem, it is actually very simple, the declaration of Class User should be inside the loop, not as a class variable, so now i create a new user at each element found and i add the old element to the array.
I have an array under another array and I want the value of the inner array and display them in UITextfield (eg : xyz,ABC,123) in iOS swift
let memberDetail = tobeReceivedArray[indexPath.row]["groupMembersVO"]
self.memberArray = memberDetail as! [AnyObject]
let amount = (tobeReceivedArray[indexPath.row]["totalPay"] as! Int) as NSNumber
let date = tobeReceivedArray[indexPath.row]["uploadOn"] as! String
let name = memberArray[indexPath.row]["name"] as! String
cell.amountLable.text = amount.stringValue cell.timeLable.text = date
cell.nameLable.text = name
You can simply use flat map for better understanding you can follow this link:
http://sketchytech.blogspot.in/2015/06/swift-what-do-map-and-flatmap-really-do.html