1 00:00:00,670 --> 00:00:05,350 With our current implementation, we display a fact when we start the app, and 2 00:00:05,350 --> 00:00:09,320 then another one when we tap the Show Fun Fact button. 3 00:00:09,320 --> 00:00:12,140 Nothing happens when we tap the button again, and 4 00:00:12,140 --> 00:00:16,760 this is because of the way we've implemented the showFunFact method. 5 00:00:16,760 --> 00:00:21,280 The code inside the method is run from top to bottom all at once. 6 00:00:21,280 --> 00:00:26,530 So even if we added a second line of code after the first one to grab the third 7 00:00:26,530 --> 00:00:31,210 fact of the array, it won't work because every time we tapped on our button, 8 00:00:31,210 --> 00:00:34,860 all the code would be run and we would only see the third fact. 9 00:00:34,860 --> 00:00:36,810 You can give it a try to see what I mean. 10 00:00:36,810 --> 00:00:38,920 So, how can we do this? 11 00:00:38,920 --> 00:00:43,680 Basically, what I want to do is every time I push the button, 12 00:00:43,680 --> 00:00:47,800 I want the app to randomly select a fact and display it. 13 00:00:47,800 --> 00:00:48,520 Okay. 14 00:00:48,520 --> 00:00:49,510 Let's think. 15 00:00:49,510 --> 00:00:52,130 How do we pull a fact out of the array? 16 00:00:52,130 --> 00:00:56,170 Well, we do that by supplying the index of the array element. 17 00:00:56,170 --> 00:01:00,210 So essentially, we need to pick a random number between zero and nine, 18 00:01:00,210 --> 00:01:04,760 and that's because we have ten facts in our array, and 19 00:01:04,760 --> 00:01:08,760 use that random number to get a fact from the array. 20 00:01:08,760 --> 00:01:13,420 Now, that doesn't seem too hard, but how do we get a random number? 21 00:01:13,420 --> 00:01:19,070 Remember, when you don't know how to proceed, first, check the documentation. 22 00:01:19,070 --> 00:01:23,730 So I'm going to go to the Help menu, Documentation and API Reference. 23 00:01:23,730 --> 00:01:26,020 When you start typing random, 24 00:01:26,020 --> 00:01:30,860 one of the first few results is about generating random numbers in iOS. 25 00:01:30,860 --> 00:01:31,720 How convenient. 26 00:01:31,720 --> 00:01:32,940 Let's check it out. 27 00:01:32,940 --> 00:01:37,820 Now, this seems overly complicated because it talks about cryptography. 28 00:01:37,820 --> 00:01:41,990 And if we go down here, says Generating Random Numbers. 29 00:01:41,990 --> 00:01:46,540 This is mostly about cryptographically secure, blah, blah, blah. 30 00:01:46,540 --> 00:01:48,330 That's too advanced for our uses. 31 00:01:48,330 --> 00:01:51,260 Now, if you can't find the information in the docs, 32 00:01:51,260 --> 00:01:54,420 the next best place to check it out is the Internet. 33 00:01:54,420 --> 00:01:58,490 So, I'm going to bring a browser onto my screen. 34 00:01:58,490 --> 00:02:05,940 And let's go to Google and type get random number ios. 35 00:02:05,940 --> 00:02:08,400 Now, if you think I'm messing around with you by Googling for 36 00:02:08,400 --> 00:02:10,160 answers, that's not the case at all. 37 00:02:10,160 --> 00:02:13,330 Now, this is a very common step in my workflow. 38 00:02:13,330 --> 00:02:16,680 If I can't figure something out, first, go to the docs, and 39 00:02:16,680 --> 00:02:20,100 then Google second, before asking anyone else for help. 40 00:02:20,100 --> 00:02:23,960 Most of the answers to any of our questions have already been answered. 41 00:02:23,960 --> 00:02:28,320 iOS has been around a long time and people have encountered these issues before. 42 00:02:28,320 --> 00:02:30,520 So, let's see what we've gotten. 43 00:02:30,520 --> 00:02:35,330 We can try this first one, Generating Random Numbers in Objective-C. 44 00:02:35,330 --> 00:02:38,160 Let's read around a bit and here's the answer. 45 00:02:38,160 --> 00:02:41,080 Wow, you can see that there's quite a bit of votes. 46 00:02:41,080 --> 00:02:43,950 So clearly, this is a popular issue. 47 00:02:43,950 --> 00:02:49,410 Now, this answer says that we should use the arc4random function and 48 00:02:49,410 --> 00:02:53,360 I'm pretty confident that this would work given the large number of upvotes. 49 00:02:53,360 --> 00:02:57,640 Then if you read around a bit more in the first comment here, it says to use 50 00:02:57,640 --> 00:03:03,070 the arc4random_uniform function because that gives a more uniform distribution. 51 00:03:03,070 --> 00:03:04,330 Let's try that. 52 00:03:04,330 --> 00:03:05,840 So let's go back to Xcode. 53 00:03:05,840 --> 00:03:07,610 I'm going to close this out. 54 00:03:07,610 --> 00:03:11,320 And go to the FactBook implementation file. 55 00:03:11,320 --> 00:03:17,350 Now down here, let's declare a method to return a random fact. 56 00:03:17,350 --> 00:03:20,750 Now, we've covered how to write Objective-C methods before. 57 00:03:20,750 --> 00:03:25,430 Let's go over it again since this is the first method we're writing ourselves. 58 00:03:25,430 --> 00:03:27,470 Now, we start with a dash or 59 00:03:27,470 --> 00:03:32,450 a hyphen, followed by the return type of the function in a set of parentheses. 60 00:03:32,450 --> 00:03:37,850 Now, in this case, our method is going to return a random fact from the array. 61 00:03:37,850 --> 00:03:40,200 And since each fact is a string, 62 00:03:40,200 --> 00:03:44,590 we're going to specify the return type as NSString. 63 00:03:44,590 --> 00:03:47,290 Next, we write out the name of the method. 64 00:03:47,290 --> 00:03:52,830 Apple has established a convention of long verbose method names in Objective-C, and 65 00:03:52,830 --> 00:03:56,940 it's common to be very descriptive when writing out our method names. 66 00:03:56,940 --> 00:04:02,750 Now, we don't really have a long name here, so let's call ours randomFact, but 67 00:04:02,750 --> 00:04:06,720 just keep in mind that if you do have a method that does something complicated, 68 00:04:06,720 --> 00:04:10,510 it's most oftentimes better to have a verbose name than trying to shorten it and 69 00:04:10,510 --> 00:04:11,640 make it look pretty. 70 00:04:11,640 --> 00:04:14,920 Now, this method doesn't accept any parameters, so 71 00:04:14,920 --> 00:04:18,810 we'll start the method body with a set of curly braces. 72 00:04:18,810 --> 00:04:20,310 Now, inside the body, 73 00:04:20,310 --> 00:04:25,840 we want to first get a random number using the arc4random_uniform function. 74 00:04:25,840 --> 00:04:30,090 This function accepts an integer as an upper bound value. 75 00:04:30,090 --> 00:04:33,240 It then returns a random number between zero and 76 00:04:33,240 --> 00:04:35,490 the upper bound, and includes zero. 77 00:04:35,490 --> 00:04:36,920 That works perfectly for 78 00:04:36,920 --> 00:04:41,420 us, and we can set the upper bound as the number of items in the array. 79 00:04:41,420 --> 00:04:44,800 We're doing it this way rather than hard-coding the value of the upper 80 00:04:44,800 --> 00:04:48,150 bound so that if we were to add more facts to our array, 81 00:04:48,150 --> 00:04:51,130 we wouldn't have to change our randomFact code. 82 00:04:51,130 --> 00:04:53,850 So first, let's create our random number. 83 00:04:53,850 --> 00:04:56,880 We'll create a variable named random of type int, and 84 00:04:56,880 --> 00:05:03,680 then use the arc4random_uniform function, self.facts.count. 85 00:05:03,680 --> 00:05:08,580 Now, the count property returns the number of items in our fact array and 86 00:05:08,580 --> 00:05:10,840 serves an, as an upper bound. 87 00:05:10,840 --> 00:05:14,420 We also need to cast the count property to an int. 88 00:05:14,420 --> 00:05:19,028 Now, this is because of an issue between a 32-bit and 64-bit integers and 89 00:05:19,028 --> 00:05:20,740 a a loss of precision. 90 00:05:20,740 --> 00:05:23,750 It's nothing that we need to worry about for now. 91 00:05:23,750 --> 00:05:28,250 Now, we cast one value to another type by specifying the type in 92 00:05:28,250 --> 00:05:31,950 parentheses before the value, just as we have done. 93 00:05:31,950 --> 00:05:33,450 Now that we have a random number, 94 00:05:33,450 --> 00:05:37,340 let's use this to retrieve a random fact from the array. 95 00:05:37,340 --> 00:05:41,955 So we can do return self.facts, and we'll use the same method, 96 00:05:41,955 --> 00:05:47,830 objectAtIndex, but instead of hard-coding a value, let's pass in random. 97 00:05:47,830 --> 00:05:52,440 Now let's go back to our ViewController and use this method to 98 00:05:52,440 --> 00:05:57,410 retrieve a random fact instead of hard-coding the array index value. 99 00:05:57,410 --> 00:06:02,050 So let's get rid of this code and just use the random method. 100 00:06:02,050 --> 00:06:02,620 Hm. 101 00:06:02,620 --> 00:06:06,400 It seems like Xcode doesn't know about this method even though we've 102 00:06:06,400 --> 00:06:09,630 successfully created an instance of the class. 103 00:06:09,630 --> 00:06:13,000 Let's go back to our FactBook implementation file. 104 00:06:13,000 --> 00:06:17,780 Now, we created this method in our implementation file, but we never put it 105 00:06:17,780 --> 00:06:22,540 in our header, and therefore, we never exposed it to any other parts of our app. 106 00:06:22,540 --> 00:06:25,390 By creating the method in our implementation file, 107 00:06:25,390 --> 00:06:28,190 we can use it anywhere inside this file. 108 00:06:28,190 --> 00:06:31,670 But when we want other classes to be able to use this method, 109 00:06:31,670 --> 00:06:34,600 we need to add it to our .h file. 110 00:06:34,600 --> 00:06:37,600 So, right under the property declaration, 111 00:06:37,600 --> 00:06:42,230 we can copy this line of code and paste it here. 112 00:06:42,230 --> 00:06:45,970 So what we're doing is declaring the method in our header. 113 00:06:45,970 --> 00:06:49,940 We start with a dash, followed by the return type, that is, 114 00:06:49,940 --> 00:06:54,960 NSString, and then an asterisk, the method name, and a colon. 115 00:06:54,960 --> 00:07:00,040 Now if we go back to our ViewController, we should be able to use this method. 116 00:07:00,040 --> 00:07:05,990 So let's get rid of self.factBooks.facts and call the randomFact method. 117 00:07:05,990 --> 00:07:09,300 Let's also change it down here, randomFact. 118 00:07:09,300 --> 00:07:14,190 And now if we run the app, we can keep clicking the button and 119 00:07:14,190 --> 00:07:16,290 we just keep getting facts. 120 00:07:16,290 --> 00:07:17,030 Great job, guys. 121 00:07:17,030 --> 00:07:17,830 We're almost there.