Accessing a dictionary entry in an array - objective-c

Basically I have an array with 3 rows, each row is a NSDictionary with 6 elements (nameLabel, name, colorLabel, color, priceLabel, price).
Example:
NSDictionary* row1 = [[NSDictionary alloc]
initWithObjectsAndKeys:#"MacBook",#"Name",#"White",#"Color",#"$1200",#"Price", nil];
Then I add those elements into an array:
NSArray* array = [[NSArray alloc] initWithObjects:row1,row2,row3, nil];
//row2 and row3 being the same as row1 but with different strings.
And then I add them to a table with subviews.
I'm trying to write an alert, which is working, but written like this, it shows a whole row in between {}. (Ex: You selected {Color = Black; Name = iPhone; Price = $600; }.
NSUInteger row = [indexPath row];
NSString *rowValue = [computers objectAtIndex:row];
NSString *message = [[NSString alloc] initWithFormat:
#"You selected %#", rowValue];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Row Selected!"
message:message
delegate:nil
cancelButtonTitle:#"No"
otherButtonTitles:nil];
[alert show];
Instead of that, I would like to only display the name of the selected element.
I realized I need to change this code segment, but don't know how to access the name element in the dictionary.
NSString *message = [[NSString alloc] initWithFormat:
#"You selected %#", rowValue];

NSUInteger row = [indexPath row];
NSDictionary *dictionary = [array objectAtIndex:row];
NSString *name = [dictionary objectForKey:#"Name"];
NSString *message = [[NSString alloc] initWithFormat:#"You selected %#",name];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Row Selected!"
message:message
delegate:nil
cancelButtonTitle:#"No"
otherButtonTitles:nil];
[alert show];

Related

Objective-C compiler error

Need help with the [currentValue, targetValue, difference]; line. It says that initializer element is not a compile-time element. Please post solution.
NSString *message = [NSString stringWithFormat:
#"The value of the slider is: %d\nThe target value is: %d\nThe difference is: %d",
[currentValue, targetValue, difference];
UIAlertView *alertView = [[UIAlertView alloc]]
initWithTitle:#"Hello, World!"
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
Should be:
NSString *message = [NSString stringWithFormat: #"The value of the slider is: %d\nThe target value is: %d\nThedifference is: %d", currentValue, targetValue, difference];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Hello, World!"
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
You have an extra '[' before current and and extra ']' after the UIAlertView alloc.

Why does isEqualToString not work for NSString?

I am trying to code the login process for an iPhone app in XCode. The problem is with the NSString serverOutput below. When I print it using printf(serverOutput.UTF8String); it prints 'Yes' to the console. However when I compare serverOutput to "Yes" it doesn't work. Any help would be appreciated. Here's my code:
- (IBAction) loginButton: (id) sender
{
// TODO: spawn a login thread
indicator.hidden = FALSE;
[indicator startAnimating];
NSString *post =[NSString stringWithFormat:#"username=%#&password=%#",userName.text, password.text];
NSString *hostStr = #"http://10.243.1.184/connectDB.php?";
hostStr = [hostStr stringByAppendingString:post];
NSData *dataURL = [NSData dataWithContentsOfURL: [ NSURL URLWithString: hostStr ]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
printf(serverOutput.UTF8String);
if([serverOutput isEqualToString:#"Yes"]){
UIAlertView *alertsuccess = [[UIAlertView alloc] initWithTitle:#"Congrats" message:#"You are authorized"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertsuccess show];
[alertsuccess release];
}
else {
UIAlertView *alertsuccess = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Username or Password Incorrect"
delegate:self cancelButtonTitle:#"OK"otherButtonTitles:nil, nil];
[alertsuccess show];
[alertsuccess release];
//[self.navigationController pushViewController:DashboardViewController animated:YES];
loginbutton.enabled = TRUE;
}
loginbutton.enabled = FALSE;
}
Based on helping others with similar situations I would say the problem is that the response from the server isn't just the string "Yes". Most likely there is some whitespace before and/or after the text. Perhaps a stray newline or two.
Try this:
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
NSLog(#"Result = '%#'", serverOutput); // look for space between quotes
serverOutput = [serverOutput stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

how to show uialertview in another thread in objective c

I created another thread and its functionality is working well. But only case is in new thread we cannot use UIControllers. As an example I couldn't use UIAlerview in new thread. How can I slove it?
My tried code is bellow.
- (IBAction)btnCopyImage:(id)sender
{
[NSThread detachNewThreadSelector:#selector(DownloadCheck) toTarget:self withObject:nil];
// [self performSelectorOnMainThread:#selector(DownloadCheck) withObject:nil waitUntilDone:NO];
NSLog(#"My name is ");
int sum =0;
for (int i=1; i<=1000; i++)
{
sum =sum+i;
}
NSLog(#"sum %d",sum);
}
-(void)DownloadCheck
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Download"];
NSString* saveDialogURL = #"/Volumes/Inbox/7. Debugging and Troubleshooting.zip";
NSString* fileNameWithExtension = saveDialogURL.lastPathComponent;
NSLog(#"path %# ",fileNameWithExtension);
NSString *pathWithExtention=[NSString stringWithFormat:#"%#/%#", path,fileNameWithExtension];
NSLog(#"path %#",pathWithExtention);
//Remove existing file
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSError *error;
[filemgr removeItemAtPath:pathWithExtention error:&error];
//Copy file to i phone created directory
if ([filemgr copyItemAtPath: saveDialogURL toPath: pathWithExtention error: NULL] == YES)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Download"
message:#"Downloaded Sucessfully"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alertView show];
NSLog (#"Copy successful");
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Download Faild"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alertView show];
NSLog (#"Copy Faild");
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
[self performSelectorOnMainThread:#selector(DownloadCheck) withObject:nil waitUntilDone:NO]; this cannot be used because it's working on same thread.
So what should I do by using same code?

Repeating UIAlert code over and over

I have this code:
-(IBAction)action2:(id)sender{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Confirm" message:#"If you press of a new group with the name you have set will be created" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: #"Ok", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Ok"])
{
NSString *destDir = [NSString stringWithFormat:#"/sandbox/%#/", namegroup.text];
NSString *filename5 = namegroup.text;
NSString *filename6 = #"group";
NSString *filename7 = #"groupdata";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *getImagePath5 = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:#"%#", filename7]];
NSMutableArray *titles = [NSMutableArray array];
[titles addObject:filename5];
NSMutableArray *keys = [NSMutableArray array];
[keys addObject:filename6];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:titles forKeys:keys];
NSString *jsonString = [dict JSONRepresentation];
NSData *jsonData = [jsonString dataUsingEncoding: NSUTF8StringEncoding];
[jsonData writeToFile: getImagePath5 atomically: YES];
[[self restClient] uploadFile:filename7 toPath:destDir
withParentRev:nil fromPath:getImagePath5];
}
}
If I press Ok button, the code is repeated over and over. how can I repeat it only 1 time??
I found out that there was another alert with the same cancel title, and when this was pressed it re-launched the same code. Thanks however for the help.

CLGeocoder Multiple Addresses?

I need to geocode two different addresses but I need to have the results inside the same scope/method. How can I direct the same variables location1 and location2 inside the same block.
Here is my current code...
- (IBAction)calculateDistance {
[textFieldDestination resignFirstResponder];
NSString *origin = [textFieldOrigin text];
if (origin) {
CLGeocoder *geoCode = [[CLGeocoder alloc] init];
[geoCode geocodeAddressString:origin completionHandler: ^(NSArray *placemarks, NSError *error) {
if (!error) {
CLPlacemark *place = [placemarks objectAtIndex:0];
CLLocation *location = place.location;
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
} else {
NSString *string = [NSString stringWithFormat:#"%# - also make sure you have inputted a valid city", [error localizedDescription]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:string delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}];
}
NSString *destination = [textFieldDestination text];
if (destination) {
CLGeocoder *geoCode2 = [[CLGeocoder alloc] init];
[geoCode2 geocodeAddressString:destination completionHandler:^(NSArray *placemarks, NSError *error) {
if (!error) {
CLPlacemark *place = [placemarks objectAtIndex:0];
CLLocation *location = place.location;
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
} else {
NSString *string = [NSString stringWithFormat:#"%# - also make sure you have inputted a valid city", [error localizedDescription]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:string delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}];
}
CLLocationDistance distanceM = [location1 distanceFromLocation:location2]; // obviously error so you can see that I need location1 and location2 in the same block.... but how!?
[metreDistance setText:[NSString stringWithFormat:#"%f", distanceM]];
}
I found out how to accomplish this. For each geocoding block, I directed to a method that had specific parameters. Pretty simple, just needed to use logic!