After an HTTP request I receive a JSON array decoded with:
NSArray *jsonArray = [stringResponse JSONValue];
The array looks like:
(
{
id = 0000000002;
ora = "15:00:00";
oraArrivo = "21:20:00";
},
{
id = 0000000001;
ora = "19:20:00";
oraArrivo = "23:30:00";
}
)
Now I have to insert every array item in one uitableview row. I tried with:
cell.textLabel.text = [self.jsonArray objectAtIndex:indexPath.row];
but it's not working. I probably need something more.
Another part of the "original" UiTableView's code I edited is:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return jsonArray.count;
}
I just need to have rows in the tableView like
"Departure time is 15:00:00 arrival time is 21:20:00"
Any suggestion on how to make it work?
Thanks.
Solved with
NSDictionary *dict = [self.jsonArray objectAtIndex: indexPath.row];
cell.textLabel.text = [dict objectForKey:#"ora"];
cell.detailTextLabel.text = [dict objectForKey:#"oraArrvo"];
Related
My function to parse an array of properties to a json object looks like this:
var jsonObject = "[{"
for i in 1...table.count {
var str = ""
var insideStr = String()
for property in properties {
let filteredTable = table.value(forKey: property) as! [Any]
insideStr += "\"\(property)\": \"\(filteredTable[i - 2])\","
}
let index = insideStr.characters.index(insideStr.startIndex, offsetBy: (insideStr.count - 2))
insideStr = String(insideStr[...index])
str += "\(insideStr)}],"
jsonObject.append(str)
}
let index = jsonObject.characters.index(jsonObject.startIndex, offsetBy: (jsonObject.count - 2))
jsonObject = "\(String(jsonObject[...index]))"
return jsonObject
}catch let error { print("\(error)") }
My question is, is it possible to skip the first property because it always returns nil data?
You could delete the first property:
delete obj[Object.keys(obj)[0]];
otherwise slice like this:
Object.entries(obj).slice(1); //array of arrays [key,value], without the first.
Replace your for loop with a for...in style loop, and then add a where clause to exclude nils since you don't want to risk dealing with them.
for tableItem in table where tableItem != nil {
// Handle json here
}
Or, you can use higher order functions to remove all the nils, and then iterate through it like this:
table.filter({ $0 != nil }).forEach({ tableItem in // Do stuff with tableItem })
I have a nsmutable array that returns a companies address. I currently having the array returning all the States. But I would like it to only return one of each State.
Current Example: Ca. Wa. Wa. Mi. Ca. And when I select a state I need to take the info to the next page. Here is my code so far.
- (NSArray *)readCompanies:(NSURL *)url {
//create a nsurlrequest with the given Url
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:
NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30.0];
//get the data
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//now create a nsdictionary from the json data
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data
options:0 error:nil];
//create a new array to hold the comanies
NSMutableArray *companies = [[NSMutableArray alloc] init];
//get an array of dictionaries with the key "company"
NSArray *array = [jsonDictionary objectForKey:#"companies"];
//iterate throught the array of dictionaries
for (NSDictionary *dict in array) {
//create a new company object with information in the dictionary
Company *company = [[Company alloc] initWithJSONDictionary:dict];
//add the Company object to the array
[companies addObject:company];
}
//return the array of Company objects
return companies;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark -table view controller methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return [companies count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"CellIDState";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil){
//single line on table view
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
// dual line on table view
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
Company *company = [companies objectAtIndex:indexPath.row];
//cell.textLabel.text = company.company_id;
cell.textLabel.text = company.state;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#",company.companyName];
//adds cheveron to tableviewl
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
thanks for the help.
Looking at your code, you have an NSMutableArray of Company objects. Then you display a table with a button for each Company's state on it.
Company 1, CA -> [CA]
Company 2, WA -> [WA]
Company 3, CA -> [CA]
If I understand your question correctly, you desire to display only a single cell for each state that has a company in it. That means you need a way to represent more than one company for each state.
One possibility for this is to have a top-level structure as a dictionary, where the key is the state and the value is an array of Company's in that state. The above three Company's would end up in this structure as:
NSDictionary
key1 (CA)
Company 1
Company 3
key2 (WA)
Company 2
The code to do this is a bit more complex than the loop you made. The readCompanies for it would look like this (please excuse my rough pseudocode):
-(NSDictionary*) readCompanies(NSURL* url) {
Get URL data
Parse URL data into array of dictionaries (you have these steps already)
NSDictionary* companyByStates = [[NSDictionary alloc] init];
//iterate throught the array of dictionaries
for (NSDictionary *dict in array) {
//create a new company object with information in the dictionary
Company *company = [[Company alloc] initWithJSONDictionary:dict];
if companyByStates does not have entry for key(company->state) {
create new NSMutableArray
add this company to new array
add array to companyByStates under key (company->state)
}
else // already have entry for that state
{
get array for that state: companyByStates[company->state]
add this company to the array for that state
}
}
return companyByStates
}
Also, your tableView method would need to use a [NSDictionary keyEnumerator] to access the indexed entry since the states are no longer an array, but keys in the top-level dictionary.
Hope that helps.
I created a database with PHPMyAdmin. Then I uploaded a php file to a web service to load the database. Now I have the url of the php file, which load the database.
This code works fine to load the database into the app:
func retrieveData() {
let url:NSURL = NSURL(string: phpURL)!
var data:NSData = NSData(contentsOfURL: url)!
json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil) as NSMutableArray
for (var i:NSInteger = 0; i < json.count; i = i + 1) {
newPlatz = json.objectAtIndex(i).objectForKey("Platz") as? NSString
newVerein = json.objectAtIndex(i).objectForKey("Verein") as? NSString
newPunkte = json.objectAtIndex(i).objectForKey("Punkte") as? NSString
newDifferenz = json.objectAtIndex(i).objectForKey("Differenz") as? NSString
newSpiele = json.objectAtIndex(i).objectForKey("Spiele") as? NSString
var myBundesliga:Bundesliga = Bundesliga.alloc()
myBundesliga.initWithBundesligaID(newPlatz, nVerein: newVerein, nSpiele: newSpiele, nDifferenz: newDifferenz, nPunkte: newPunkte)
bundesligaArray = NSMutableArray.alloc()
//bundesligaArray.addObject(myBundesliga)
println("\(newPlatz!);\(newVerein!);\(newPunkte!);\(newDifferenz!);\(newSpiele!)")
}
}
The output in the console:
1;FC Bayern München;17;13;7
2;TSG Hoffenheim;13;5;7
3;Bor. Moenchengladbach;13;5;7
4;Bayer 04 Leverkusen;12;2;7
5;1. FSV Mainz 05;11;4;7
and so on...
It works perfectly. But now i do not know how to display the data in my tableview. As you can see in the code above, the line code behind the two slashes do not work perfectly. Always when i run the app there is a 'Thread 1: breakpoint 1.1' error in this line:
bundesligaArray.addObject(myBundesliga)
I do not know why. Can somebody help me?
The problem is how you're instantiating your objects. You have:
bundesligaArray = NSMutableArray.alloc()
That should be:
bundesligaArray = NSMutableArray()
And, of course, you want to define that before your for loop, not inside it.
Or, if you wanted to use a Swift array, you'd define bundesligaArray as:
var bundesligaArray: [Bundesliga]?
And you'd instantiate it with
bundesligaArray = [Bundesliga]()
And you'd add objects to it with
bundesligaArray?.append(myBundesliga)
I am new to xcode and I seem to be stuck at trying to create a tableview with sections.
My code below creates the header however I cannot seem to display the rows that belong to the section. I'm sure it has to do with the multidimensional array. I say this because "dobSection" value is "results" when I suppose it should display the dates under "DOB".
I have spent hours trying many different ways to get this to work..... eh! No luck.
The Json is somewhat like this:
{"results":
[{"name":"joe","surname":"blow","DOB":"1990-01-01"},
{"name":"jane","surname":"doe","DOB":"1990-01-01"},
{"name":"john","surname":"doe","DOB":"1995-06-06"}]
}
and the code
NSMutableArray *jsonResults;
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
jsonResults = [json objectForKey:#"results"];
self.dob = json;
self.keys = [jsonResults valueForKey:#"DOB"];
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [keys count];
//return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
// NSString *key = [keys objectAtIndex:section];
NSString *key = [keys objectAtIndex:section];
NSArray *dobSection = [dob objectForKey:key];
return [dobSection count];
}
in addition by replacing this:
NSArray *dobSection = [dob objectForKey:key];
with
NSArray *dobSection=[[games objectForKey:#"results"]valueForKey:#"dob"];
I get all rows.
I cannot get them to group by DOB
My code above may be flawed however I would love some input on how to get this right.
Thank you
I need help in retrieving a JSON object and parsing the array into my UIPickerView with 2 columns. One column is the data retrieve from JSON, the other column is hard coded.
Is there any sample codes for parsing the JSON into the UIPickerView column?
I got you some code to get you started, but please keep in mind that:
It is not optimized code (for example the call you make to fetch your data is executed in the main thread. In case you need to fetch large amounts of data you must make asynchronous calls).
Its crucial to understand how the UIPickerView delegate & datasource is implemented.
I hope that this will get you on the right track...
// Get your JSON Data
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.mydomain.com/myjson.json"]];
// Convert your JSON object to an 'NS' object
NSError *error;
id myJsonObj = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:&error];
// Extract any data from your JSON object
NSArray *myFirstArray = ...; // Your fixed array
NSArray *mySecondArray = ...; // An array with data from your JSON
// In your UIPIckerView datasource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
switch(component)
{
case 0:
// First component
return [myFirstArray count];
break;
case 1:
// Second component
return [mySecondArray count];
break;
default:
return 0;
break;
}
return 0;
}
// In your UIPIckerView delegate
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
switch(component)
{
case 0:
// First component
return [myFirstArray objectAtIndex:row]; // We assume that you got NSString objects in the array
break;
case 1:
// Second component
return [mySecondArray objectAtIndex:row]; // We assume that you got NSString objects in the array
break;
default:
return 0;
break;
}
return #"";
}