Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Create method to pull random strings from array

So I have an array that contains a dictionary that contains an array, and I want to create a method that randomly selects a string within my array and returns it. I want to have the label in my app to change to a random fact from a specified array containing multiple strings. Any help would be appreciated.

Here's my library array that I want to create my randomFact method. I've made a randomFact method, but every time I tap my buton to trigger my "showNewFact" method, my app crashes.

#import "FactBook.h"

NSString *const kTitle = @"title";
NSString *const kFacts = @"facts";
NSString *const kIcon = @"icon";
NSString *const kBackgroundColor = @"backgroundcolor";

@implementation FactBook


- (instancetype)init {

    self = [super init];
    if (self) {
                   _library = @[@{kTitle: @"Random",
                       kIcon: @"random.pdf",
                       kBackgroundColor: @{@"red": @236.0, @"green": @81.0, @"blue": @59.0, @"alpha": @1.0},
                       kFacts: @[@"When hippos are upset, their sweat turns red."
                                 ,@"The average woman uses her height in lipstick every 5 years."
                                 ,@"Cherophobia is the fear of fun."
                                 ,@"In the UK, it is illegal to eat mince pies on Christmas Day!"
                                 ,@"A flock of crows is known as a murder."

- (NSString *)randFact {

    int random = arc4random_uniform((int)self.library.count);

    return [self.library objectAtIndex:random];

}
Michael Hulet
Michael Hulet
47,913 Points

Could you post the rest of FactBook.m and FactBook.h? What's the error getting when you crash? Also, I feel like it'd be better if library was its own object instead of just an NSDictionary. It'd be far more type-safe and reusable that way

2 Answers

Here's the all of the Factbook.m and FactBook.h; I have a bunch of facts for my app hard coded just because I haven't learned how to pull information from the web just yet.

FactBook.m
#import "FactBook.h"

NSString *const kTitle = @"title";
NSString *const kFacts = @"facts";
NSString *const kIcon = @"icon";
NSString *const kBackgroundColor = @"backgroundcolor";

@implementation FactBook


- (instancetype)init {

    self = [super init];
    if (self) {

        _library = @[@{kTitle: @"Random",
                       kIcon: @"random.pdf",
                       kBackgroundColor: @{@"red": @236.0, @"green": @81.0, @"blue": @59.0, @"alpha": @1.0},
                       kFacts: @[@"When hippos are upset, their sweat turns red."
                                 ,@"The average woman uses her height in lipstick every 5 years."
                                 ,@"Cherophobia is the fear of fun."
                                 ,@"In the UK, it is illegal to eat mince pies on Christmas Day!"
                                 ,@"A flock of crows is known as a murder."
                                 ,@"Bananas are curved because they grow towards the sun."
                                 ,@"If you lift a kangaroo's tail off the ground it can't hop."
                                 ,@"Banging your head against the wall burns 150 calories an hour."
                                 ,@"Pteronophobia is the fear of being tickled by feathers!"
                                 ,@"\"FaceBook Addiction Disorder\" is a mental disorder identified by Psychologists."
                                 ,@"May 29th is officially \"Put a Pillow on Your Fridge Day.\""
                                 ,@"Human saliva has a boiling point three times that of regular water."]
                       },
                     @{kTitle: @"Dogs",
                       kIcon: @"dog.pdf",
                       kBackgroundColor: @{@"red": @236.0, @"green": @140.0, @"blue": @37.0, @"alpha": @1.0},
                       kFacts: @[@"Puppies have 28 teeth and normal adult dogs have 42.",
                                 @"You can lower your blood pressure just by petting your pup!",
                                 @" Corgi is Welsh for \"dwarf dog.\"",
                                 @" Anything smelly your dog rolls in only smells gross to you--to them it's DIVINE.",
                                 @"Dogs have wet noses because it helps to absorb scent chemicals.",
                                 @"If you leave your dog a piece of clothing that smells like you, the scent will comfort them and it can help curb their separation anxiety.",
                                 @"The basenji is the only breed of dog that can't bark, but they can yodel!",
                                 @" When dogs poop, they prefer to do it in alignment with the Earth's magnetic field.",
                                 @"If a guy has a dog with him, he's three times more likely to get a girl's phone number."]
                       },
                     @{kTitle: @"Food",
                       kIcon: @"food.pdf",
                       kBackgroundColor: @{@"red": @236.0, @"green": @206.0, @"blue": @180.0, @"alpha": @1.0},
                       kFacts: @[@"Pringles once had a lawsuit trying to prove that they weren't really potato chips.",
                                 @"The oldest evidence for soup is from 6,000 B.C. and calls for hippopotamus and sparrow meat.",
                                 @" Ripe cranberries will bounce like rubber balls.",
                                 @"Consuming dairy may cause acne.",
                                 @"An average ear of corn has an even number of rows, usually 16.",
                                 @" One of the most popular pizza toppings in Brazil is green peas.",
                                 @"Oklahoma's state vegetable is the watermelon.",
                                 @"About 70% of olive oil being sold is not actually pure olive oil.",
                                 @"The most expensive pizza in the world costs $12,000 and takes 72 hours to make.",
                                 @" Chocolate was once used as currency.",
                                 @"The tea bag was created by accident, as tea bags were originally sent as samples.",
                                 @" Humans are born craving sugar."]
                       },
                     @{kTitle: @"Space",
                       kIcon: @"space.pdf",
                       kBackgroundColor: @{@"red": @94.0, @"green": @236.0, @"blue": @70.0, @"alpha": @1.0},
                       kFacts: @[@"The Milky Ways central core contains a supermassive black hole. It is commonly referred to as Sagittarius A*. It contains the mass of about 4.3 million Suns.",
                                 @"Galaxies can collide.",
                                 @"There are over 100 billion galaxies in the universe.",
                                 @"There are over 300 billion stars in our galaxy, the Milky Way.",
                                 @"Universe is estimated to be 13.82 billion years old.",
                                 @" The most massive star, and one of the hottest that we know of, is the RMC 136a1",
                                 @" The biggest known star currently is UY Scuti",
                                 @" Light year is a measure of distance, not time.",
                                 @"Neutron stars can spin at a rate of 600 rotations per second.",
                                 @"All of space is completely silent.",
                                 @"There is an uncountable number of stars in the known universe.",
                                 @"The Apollo astronauts' footprints on the moon will probably stay there for at least 100 million years."]
                       },
                     @{kTitle: @"Science",
                       kIcon: @"science.pdf",
                       kBackgroundColor: @{@"red": @55.0, @"green": @64.0, @"blue": @236.0, @"alpha": @1.0},
                       kFacts: @[@"41 new species are discovered by scientists every single day.",
                                 @"Until the 1960s, the only reliable pregnancy test was to inject a womans urine into a female African clawed frog. If the woman was pregnant, the frog would ovulate within 12 hours.",
                                 @"About 65 billion neutrinos will pass through your fingernail in a second",
                                 @"Light would take .13 seconds to travel around the Earth.",
                                 @" If you drilled a tunnel straight through the Earth and jumped in, it would take you exactly 42 minutes and 12 seconds to get to the other side.",
                                 @"A single bolt of lightning contains enough energy to cook 100,000 pieces of toast.",
                                 @"A medium-sized cumulus cloud weighs about the same as 80 elephants.",
                                 @"The average person walks the equivalent of three times around the world in a lifetime."]
                       },
                     @{kTitle: @"Movies",
                       kIcon: @"movies.pdf",
                       kBackgroundColor: @{@"red": @0.0, @"green": @219.0, @"blue": @236.0, @"alpha": @1.0},
                       kFacts: @[@"The original cut of The Wolf of Wallstreet had over four hours worth of content so had to be cut further.",
                                 @"Michael Caine was so terrified of Heath Ledger's Joker in The Dark Knight that he forgot his lines in the first scene they shot together.",
                                 @"Stanley Kubrick destroyed almost all of his props and sets from 2001: A Space Odyssey because he didn't want them to be used in any lesser science fiction films.",
                                 @"The movie Titanic cost more money to film than the actual ship cost to build.",
                                 @"Jim Caviezel was struck by lightning while filming the Sermon on the Mount in The Passion of the Christ.",
                                 @"Psycho was the first movie to ever show a toilet being flushed.",
                                 @"The Michael Myers face mask in Halloween is just a Captain Kirk/William Shatner face mask that's painted white.",
                                 @" Gal Gadot was actually five months pregnant while filming the reshoots for Wonder Woman."]
                       },
                     @{kTitle: @"Tv Shows",
                       kIcon: @"tvshows.pdf",
                       kBackgroundColor: @{@"red": @236.0, @"green": @23.0, @"blue": @73.0, @"alpha": @1.0},
                       kFacts: @[@" In Breaking Bad, Jesse Pinkman was originally supposed to die at the end of Season 1, but Vince Gilligan picked up on the chemistry between Bryan Cranston and Aaron Paul and rewrote the plot. No pun intended.",
                                 @"Walter's flustered pizza toss in Season 3 was actually a complete fluke and was done in just one take. (Breaking Bad)",
                                 @"Emilia Clarke, who plays Daenerys in Game of Thrones, voiced Dr. Zoidberg's girlfriend in the final episodes of Futurama.",
                                 @"To make their reactions as genuine as possible, the majority of the cast have not read the Game of Thrones books.",
                                 @"One Tree Hill was named after a U2 song of the same name, which is about a landmark in New Zealand.",
                                 @" Michael Keaton was originally cast to play Jack in Lost.",
                                 @"Americans cast more votes in the election of Taylor Hicks than the 1984 presidential election of Ronald Reagan.",
                                 @"Philo Farnsworth, the inventor of the modern television, wouldn't let his kids watch TV."]
                       },
                     @{kTitle: @"Basketball",
                        kIcon: @"basketball.pdf",
                       kBackgroundColor: @{@"red": @236.0, @"green": @110.0, @"blue": @4.0, @"alpha": @1.0},
                       kFacts: @[@"Michael Jordan was fined $5,000 by commissioner David Stern, for showing off the first of his series of high-tops in 1985, for every game he played them in.",
                                 @"In the 20102011 season, the Cleveland Cavaliers set a league record by losing 26 basketball games in a row.",
                                 @"Karl Malone of the Utah Jazz holds the record for the most free throws at 9,787 in his career.",
                                 @"Lynette Woodward (1959) was the first female Globetrotter basketball team player.",
                                 @"Adidas manufactures all the NBA uniforms.",
                                 @"The smallest city that has an NBA franchise is Salt Lake City.",
                                 @"The average height of all NBA players is just under 67 inches for the men and just over 57 inches for women.",
                                 @"Kobe Bryant was the youngest player to start an NBA game at just 18.5 years old.",
                                 @"All NBA courts are made of maple wood, which is strong but also flexible, to help players jump and land safely."]
                       },
                     @{kTitle: @"Comics",
                       kIcon: @"comics.pdf",
                       kBackgroundColor: @{@"red": @236.0, @"green": @221.0, @"blue": @17.0, @"alpha": @1.0},
                       kFacts: @[@"Michael Jackson wanted to play Spider-Man in a movie, so he tried to buy Marvel comics in the '90s.",
                                 @"The world's largest comic book collection belongs to the Library of Congress. They currently hold over 100,000 individual issues.",
                                 @"Nicolas Coppola took his stage name, Nic Cage, from the Marvel character Luke Cage.",
                                 @"Our universe actually exists in the Marvel multiverse. Our Earth is Earth-1218.",
                                 @"Technically, Gotham City is in New Jersey, and Metropolis is in Delaware.",
                                 @"Wayne Enterprises, which is controlled by Batman's alter ego, Bruce Wayne, owns The Daily Planet, the newspaper that Superman's alter ego, Clark Kent, works for.",
                                 @"Spider-man has a hyphen in it so that people don't confuse him with Superman.",
                                 @" In an alternate reality, Peter Parker is bitten by a radioactive sheep, turning him into a hero named Sheep-Boy."]
                       },
                     @{kTitle: @"Soccer",
                       kIcon: @"soccer.pdf",
                       kBackgroundColor: @{@"red": @55.0, @"green": @236.0, @"blue": @127.0, @"alpha": @1.0},
                       kFacts: @[@"No one knows exactly when soccer was created, but the earliest versions of the game can be traced back 3,000 years.",
                                 @"There are 32 panels on a traditional soccer ball, one for each country in Europe.",
                                 @"A professional soccer player runs 48 kilometers, or 3.9 miles, in an average soccer game.",
                                 @"Until 1908, soccer balls were made from the inflated stomach tissue of executed Irish prisoners.",
                                 @"In most countries, a soccer players uniform is called a \"kit.\" The cleats are called \"hooves.\"",
                                 @"The national sport of Canada is soccer.",
                                 @"Soccer was illegal in Mississippi until 1991."]
                       },
                     @{kTitle: @"Anatomy",
                       kIcon: @"anatomy.pdf",
                       kBackgroundColor: @{@"red": @37.0, @"green": @17.0, @"blue": @236.0, @"alpha": @1.0},
                       kFacts: @[@"A human head remains conscious for about 15 to 20 seconds after it is been decapitated.",
                                 @"Nerve impulses to and from the brain travel as fast as 170 miles per hour.",
                                 @"The brain operates on the same amount of power as 10-watt light bulb.",
                                 @"The human brain cell can hold 5 times as much information as the Encyclopedia Britannica.",
                                 @"Your brain uses 20% of the oxygen that enters your bloodstream.",
                                 @"The brain is much more active at night than during the day.",
                                 @"Scientists say the higher your I.Q. the more you dream.",
                                 @"Facial hair grows faster than any other hair on the body.",
                                 @"Womens hair is about half the diameter of mens hair.",
                                 @"One human hair can support 3.5 ounces."]
                       },
                     @{kTitle: @"Music",
                       kIcon: @"music.pdf",
                       kBackgroundColor: @{@"red": @143.0, @"green": @225.0, @"blue": @236.0, @"alpha": @1.0},
                       kFacts: @[@"The chills you get when you listen to music, is mostly caused by the brain releasing dopamine while anticipating the peak moment of a song.",
                                 @"An emotional attachment could be the reason for your favorite song choice.",
                                 @"In retail stores slow music is played to keep you shopping and spend more. In restaurants fast music is played to speed up turnaround.",
                                 @" Hans Zimmer, the composer/producer for over 150 movies, including The Lion King, Gladiator, all Pirates of the Caribbean movies, Pearl Harbor, Rush, Inception, the Dark Knight, etc.; had only 2 weeks of formal music education",
                                 @"There is a music piece calledAs Slow as Possiblewhich started in 2001 and has a duration of 639 years. It can take years for a single note to be played.",
                                 @"When Beethoven went deaf, he composed his music by hacking the legs off his piano and sitting on the floor so he could feel the vibrations.",
                                 @"A Sea Organ in Croatia continuously plays music powered by waves that flow through tubes located underneath a set of large marble steps."]


                       }];


    }

    return self;


}

- (NSString *)randFact {

    int random = arc4random_uniform((int)self.library.count);

    return [self.library objectAtIndex:random];

}


@end
FactBook.h
#import <Foundation/Foundation.h>

extern NSString *const kTitle;
extern NSString *const kFacts;
extern NSString *const kIcon;
extern NSString *const kBackgroundColor;

@interface FactBook : NSObject

- (NSString *)randFact;


@property (strong, nonatomic) NSArray *library;


@end

Here is the error I'm getting when I tap the button that triggers my "showNewFact" method.

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DisplayFactsViewController showNewFact]: unrecognized selector sent to instance

Also here is my 2 viewcontroller .m and .h files

#import <UIKit/UIKit.h>

@class FactBook;
@class ColorWheel;
@class FactsLibrary;

@interface DisplayFactsViewController : UIViewController

@property (strong, nonatomic) FactsLibrary *library;
@property (strong, nonatomic) FactBook *factBook;
@property (strong, nonatomic) ColorWheel *colorWheel;

@property (weak, nonatomic) IBOutlet UIButton *factColorButton;
@property (weak, nonatomic) IBOutlet UILabel *funFactLabel;


@end


#import "DisplayFactsViewController.h"
#import "FactBook.h"
#import "ColorWheel.h"
#import "FactsLibrary.h"


@implementation DisplayFactsViewController

// changes background/button to random color. Label to random fact.
- (IBAction)showNewFact:(id)sender {

    UIColor *randomColor = [self.colorWheel randomColor];

    self.view.backgroundColor = randomColor;
    self.factColorButton.tintColor = randomColor;


    self.funFactLabel.text = [self.factBook randFact];



}

//Library instance passed from category page, background/buttontint set to random color
- (void)viewDidLoad {
    [super viewDidLoad];

    self.factBook = [[FactBook alloc] init];
    self.colorWheel = [[ColorWheel alloc] init];


    UIColor *randomColor = self.colorWheel.randomColor;

    self.view.backgroundColor = randomColor;
    self.factColorButton.tintColor = randomColor;


    if (self.library) {
        self.funFactLabel.text = self.library.categoryFacts[1];
        self.navigationItem.title = self.library.categoryTitle;

    }



}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}



@end



#import <UIKit/UIKit.h>
@class FactBook;
@class ColorWheel;
@class DisplayFactsViewController;

@interface CategoryPageViewController: UIViewController

@property (strong, nonatomic) FactBook *factBook;
@property (strong, nonatomic) ColorWheel *colorWheel;
@property (strong, nonatomic) DisplayFactsViewController *facts;

@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *categoryImages;


@end


#import "CategoryPageViewController.h"
#import "ColorWheel.h"
#import "FactBook.h"
#import "DisplayFactsViewController.h"
#import "FactsLibrary.h"


@implementation CategoryPageViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    //Creates library instance for each image in category page
    for (NSUInteger index = 0; index <self.categoryImages.count; index++ ) {

        FactsLibrary *library = [[FactsLibrary alloc] initWithIndex:index];

        UIImageView *categoryImageView = self.categoryImages[index];

        categoryImageView.image = library.imageIcon;
        categoryImageView.backgroundColor = library.backgroundColor;

    }

}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}



/* Determines which image was tapped, then passes index value over to library instance

 where then the correct information is displayed when segue is performed
*/
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if ([segue.identifier isEqualToString:@"categoryToDisplay"]) {


        UIImageView *categoryImageView = (UIImageView *)[sender view];

        if ([self.categoryImages containsObject:categoryImageView]) {

            NSUInteger index = [self.categoryImages indexOfObject:categoryImageView];


            DisplayFactsViewController *displayFactsViewController = (DisplayFactsViewController *)segue.destinationViewController;

            displayFactsViewController.library = [[FactsLibrary alloc] initWithIndex:index];
        }

    }

}

- (IBAction)showFactPage:(id)sender {

    [self performSegueWithIdentifier:@"categoryToDisplay" sender:sender];
}




@end