Group TableView items from NSArray returned in JSON Response in Swift - ios

I have a table view and I want to populate the table view with the values provided to me in a JSON response in the form of NSArray and I have used the code below to extract this NSArray:
dispatch_async(dispatch_get_main_queue(), {
print(json)
if let listDictionary = parseJSON["list"] as? NSArray {
print("LIST: \(listDictionary)")
}
})
In JSON response, I get the following array of two elements as shown below:
list = (
{
"is_cover" = 0;
"is_recommand" = 0;
name = "Helena's Signature Dish";
ord = 5;
price = "105.00";
remark = "Helena's special made dish is one of the most priced and delicious dishes in the whole world.";
thumb = "56c351887a0e0.jpg";
},
{
"is_cover" = 0;
"is_recommand" = 0;
name = "Pineapple Fried Rice";
ord = 6;
price = "110.00";
remark = "We have the most delicious pineapple rice in the whole world!";
thumb = "56c704e15da79.jpg";
}
);
Now I want to show the value "name", "price" and "remark" fields from each element in the array into a UITableView.
But I can't find a way to break the values for name, price and remark for each element and put them into an another array so they can be displayed in a table view somehow because each element contains a very long string and I only need to extract some values from this string. Can anyone please help me with this as I'm very new to Swift.
Thanks!

You don't need to make a second array, Only extarct particular json from array in cellForRowatIndexPath on dictinary by objectatindex method of array and now you can access.

You can achieve it by creating a model Class which contains only
those properties which you needed.
Once you get the response array from server , iterate though each
dictionary and create a Model Object.Add this model objects in the
Array.
Use this model object in the Array for applying data in your cell using the index
One more thing to add is always prefer using objects as it gives (.)dot syntax & autosuggestion, so there will be less chances of
making mistakes. As if you use Dictionary there will be more chances
of using incorrect key getting crash

I fixed this by putting values in "name", "price" and "remark" fields into another array using flatMap as shown below:
let nameArray = listArray.flatMap({ element in (element["name"] as? String)! })
And then I got something like:
Name's: (
"Helena's Special Dish",
"Pineapple Fried Rice"
)
and then in the tableView function for cellForRowAtIndexPath I grouped the values in tableview.

Related

fill dictionary values in loop

I have a dictionary var items = [String:String]()
Then I assign values :
for i in itemInCart {
items["param_id"] = i.modelId
//items["param_id"]?.append(i.modelId!)
}
print(items)
I have just a last value.
I know that the method append() is not applicable to dictionaries, but how can I fill it then?
This is because you are replacing param_id every time for loop i so it will always a last element you will found
You have two options, either create a unique key for each element (a bad idea) or if you want all the elements you have to create array and add it into the param_id key like:
items["param_id"] = itemInCart.map { $0.modelId }
so now your dictionary is [String:Any]() or [String:[String]]()

How to access key from [Any] using swift

Am developing a application using swift,in my am integrating cometchat following the link https://docs.cometchat.com/ios-sdk/quick-start/. So am fetching chat history from the server.
Now I got two(sender messages and receiver messages) nsmutablearray value from the server.
i.e., var firstArr = response!["history"]! as! NSMutableArray
var secondArr = response!["history"]! as! NSMutableArray
I merged two nsmuatblearray values and the result i got is:
[
{
from = 1;
id = 68;
localmessageid = "46A9A5E5-FEEC-4588-B7D6-18E88BA68393_2";
message = "ckeck messages";
"message_type" = 10;
old = 1;
self = 1;
sent = 1521185409000;
},
{
from = 2;
id = 69;
localmessageid = "46A9A5E5-FEEC-4588-B7D6-18E88BA68393_1";
message = "sent to thiyakarajan";
"message_type" = 10;
old = 1;
self = 1;
sent = 1521185410000;
}
]
In the responses key value sent is refered as timestamp.
using that sent key(timestamp) help me to sort array in ascending
order.
And also me to load message value in table view.
Thanks
You can access the Array in cellforrowatindexpath method of your TableView by using code like [[yourarray objectAtIndex:indexPath.row]objectForKey:#"message"]. By using this line you can access the value of message of the array at indexPath 0. Also for sorting the Array depending on timestamp please refer the below code:
NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: #"sent" ascending: YES];
return [myArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
We have used the same in our ReadyUI code. Please refer our ReadyUI source code and email us at support#cometchat.com if you need additional assistance.
It's a very bad practice working with network data like that. Especially if you want to use this data further inside of your app.
You need to parse the data received either in Dictionary or in your own data structure to work with it safely. There're plenty of ways to do that including JSONSerialization, Codable Protocol or even external libraries like SwiftyJSON
After parsing you will have your objects that you can work with without necessity of casting Any type to expected types, which brings a lot of optional checks. So let's say you have your structure called Message that contains all the data from JSON, after getting all the objects you'll have your neat [Message] array that you can pass around the application.
To sort array by some of the properties you simply use function sorted(by:) that is default for any collection. In your case: sortedArray = myArray.sorted(by: {$0.sent < $1.sent})
Now you can use this array as a dataSource for your tableView using UITableViewDataSource protocol
It's obvious that you're pretty new to iOS programming, so I'd recommend to look up for some tutorials on working with networking data. You can watch this video for example, it pretty much sums up everything mentioned above.
Do code like this
Save Swift Array
var firstArr : Array<Dictionary<String, Any>> = response!["history"]! as! Array<Dictionary<String, Any>>
Access valus
let strMessage : String = fistArr[index]["message"] as! String
Will works..!

Accessing Dictionary element for a tableview

I have passed a dictionary to a second view controller and assigned it to an array, I thought I could access the data easier this way:
var myAlerts: NSDictionary!
The dictionary has three elements for each: Id (which I don't care about), alertDate, and alertNote.
I'm trying to get these elements into a tableView but struggling with this.
I thought about just moving it into two arrays and accessing it that way, cumbersome but it at least gets me further down the road so to speak.
Here is the raw data from the dictionary AFTER it was past to the second controller:
{
alerts = (
{
alertDate = "2017-07-16";
alertNote = "Rob is the worlds greatest friend";
id = 2;
},
{
alertDate = "2017-07-17";
alertNote = "This is a test of the emergency system";
id = 1;
}
);
}
When I tried to move the values into two arrays with this:
func CreateArray() {
for i in 0...myAlerts.count {
alertsDate[i] = myAlerts["alerts"]["alertDate"]
alertsNote[i] = myAlerts["alerts"]["alertNote"]
}
}
I get the proverbial Type Any? has no subscript members.
Any help would be appreciated.
myAlerts with that data is now a dictionary containing an array of dictionaries. (so top level is a dictionary, with one key/value pair which is of type array of [String:Any] objects).
Since a dictionary value is of type Any, it can't infer in this case what the type of the value for the key alerts is. So you have to try cast it to a specific type first, in this case an array of dictionaries, i.e. [[String:Any]]
So this should get rid of your error:
func CreateArray() {
for i in 0...myAlerts.count {
let alertArray = myAlerts["alerts"] as! [[String:Any]]
alertsDate.append(alertArray[i]["alertDate"] as! String)
alertsNote.append(alertArray[i]["alertNote"] as! String)
}
}
Note: I had to change alertsDate and alertsNote arrays to using append as in my demo code i had no existing items in the array and using and index would have caused an error.

I'm having trouble fetching entities from core data based on relationships with predicates

Quick background: I have en ExamEntity, which is linked via a relationship to sections covered in the exam (SectionEntity), which is linked via a relationship to the subsections under each section (SubsectionEntity).
What I'm try to do is fetch the sections and related subsections which will be covered be a selected Exam, and store them in a dictionary which can hold multiple string values per key.
My code starts like this:
var sectionsDictionary = [String:[String]]()
//---Fetch Section Entity
let sectionPredicate = NSPredicate(format: "(exam = %#)", selectedExam)
let sectionsFetchRequest:NSFetchRequest = SectionEntity.MR_requestAllWithPredicate(sectionPredicate)
let fetchedSections:NSArray = SectionEntity.MR_executeFetchRequest(sectionsFetchRequest)
All good here. But then I try and fetch the subsections related to the selected sections and things go wrong.
following Code:
for section in fetchedSections {
let sectionName = section.valueForKey("name") as! String
// //error occurs on the line below
let subsectionPredicate = NSPredicate(format: "(section = %#)", section as! SectionEntity)
let subsectionsFetchRequest:NSFetchRequest = SubsectionEntity.MR_requestAllWithPredicate(subsectionPredicate)
let fetchedSubsections:NSArray = SubsectionEntity.MR_executeFetchRequest(subsectionsFetchRequest)
The error I get is:
Could not cast value of type 'NSManagedObject_SectionEntity_' (0x7fb363e18580) to 'MyApp.SectionEntity' (0x10c9213e0).
The next few lines are supposed to iterate through the fetched results, adding their names as values to the dictionary with section names as keys.
for subsection in fetchedSubsections{
let subsectionName = subsection.valueForKey("name") as! String
sectionsDictionary[sectionName] = [subsectionName]
}
}
thanks in advance.
You're not defining the type of the class for your record
Go to the Project.xcdatamodeld file, and select your SectionEntity
Check if the field Class is like this
If it is then write in the Class field "SectionEntity" and press Enter, it should be like this
Then try again
You need to make sure that the elements of the collection you enumerate are of the correct type.
Presumably, Magical Record will return an NSArray of NSManagedObject items. You need to make sure Swift knows what type section is.
for object in fetchedSections {
let section = object as! SectionEntity
// ...
}
Also, see my answer about the unsuccessful casts to NSManagedObject subclasses.

Cannot assign a value of type '[(String)]' to a value of type 'String!'?

woodText.text = [String](textForWood.values) This is my code. woodText is a UITextView, and textForWood is a dictionary. Please help.
woodText.text = textForWood["Oak"] as! String
You need to assign a String to the text of a UITextView. The above shows how to extract a String from a Dictionary.
Addition based on the comments
I don't think using a dictionary to populate a table view is a good idea. (Remember, dictionaries are not ordered, arrays are.) You should have an array of some kind that informs the table view how many rows it should display and what to display in those rows.
One solution would be an array of dictionaries ([[String : String]]). You can then populate each cell in cellForRowAtIndexPath. The dictionary for each row should contain something like
["name" : "Oak", "text" : "The text to display in the oak cell..."]
Use the standard boilerplate code to dequeue the cell with the text view and then
let woodDictionary = textForWood[indexPath.row]!
woodText.text = woodDictionary["text"] as! String
It would be much better to use a simple object.
struct Wood {
let name: String
let text: String
}
try this:
var string = ""
for value in textForWood.values.array {
string = string.stringByAppendingString("\(value), ")
}
woodText.text = string
hope this helps.

Resources